I need to make a separate create action for the nested Answer resource, such as create_xhr, which will be called in the form on the parent resource.
This is what the route for the Answer resource looks like:
namespace :admin do
resources :tests do
resources :questions, shallow: true, except: %i[index] do
resources :answers, shallow: true, except: %i[index]
end
end
end
The path should look something like this:
post '/questions/:question_id/answers/create_xhr
So that in the Answers controller, the new object is associated with the current Question.
Now I've come to an option:
namespace :admin do
resources :tests do
resources :questions, shallow: true, except: %i[index] do
resources :answers, shallow: true, except: %i[index] do
post :create_xhr, on: :new
end
end
end
end
I get the route:
create_xhr_new_admin_question_answer POST /admin/questions/:question_id/answers/new/create_xhr(.:format) admin/answers#create_xhr
And then I create a form on the show page for Question:
<%= form_with url: create_xhr_new_admin_question_answer_path(@question), local: false do |form| %>
But the parameters of the new Answer do not come inside the "answer" key:
Parameters: {"authenticity_token"=>"[FILTERED]", "body"=>"text", "correct"=>"false", "commit"=>"Add answer", "lang"=>"en", "question_id"=>"7"}
It must be:
Parameters: {"authenticity_token"=>"[FILTERED]", "answer"=>{"body"=>"text", "correct"=>"false"}, "commit"=>"Add answer", "lang"=>"en", "question_id"=>"7"}
If I specify a model in the form instead of a URL, then rails selects the default action create.
I also tried writing the route directly in the Admin namespace block:
post '/questions/:question_id/answers/create_xhr', to: 'answers#create_xhr', as: :create_answer_on_question
and get a route:
admin_create_answer_on_question POST /admin/questions/:question_id/answers/create_xhr(.:format) admin/answers#create_xhr
However, the problem with the parameters coming to the controller is the same.
Where am I wrong?
Should I write the router or the form differently?
OK, in the form you must specify both the model and the path. In the end, it all looks like this:
namespace :admin do
resources :tests do
resources :questions, shallow: true, except: %i[index] do
resources :answers, shallow: true, except: %i[index]
end
end
post '/questions/:question_id/answers/create_xhr', to: 'answers#create_xhr', as: :create_answer_on_question
end
and form:
<%= form_with model: [:admin, @question, @question.answers.new ], url: admin_create_answer_on_question_path(@question), local: false do |form| %>
Then Answer parameters come nested in the controller.
Inside the resources :answers block, I couldn't find a way to normally spell the action without new in the path.