I followed the Railscast for editing multiple records at the same time in one form. linked here: http://railscasts.com/episodes/165-edit-multiple-revised
This worked great for editing multiple onboarding_steps on the same form modal. Basically we mark the completion date of each step and hit save.
But now, one of these steps has a checklist of things to collect before it can be completed, and they want to put the checklist on the same form. And once I added in the <%= f.fields_for :onboarding_checkbox, onboarding_step.onboarding_checkbox do |checkboxes_form| %>
section the form broke and threw a No route matches [POST]
because the form is supposed to use PUT. For some reason adding in the nested attributes makes it want to do a POST instead of PUT.
This is it working properly before the nested attributes were added:
Started PUT "/onboarding_steps/update_multiple" for ::1 at 2018-06-15 15:25:25 -0500
Processing by OnboardingStepsController#update_multiple as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"",
"onboarding_steps"=>{"531"=>{"completed_date"=>""}, "280"=>{"completed_date"=>"02/09/2018"}}}, "commit"=>"Update"}
This is what it's doing with the nested section:
Invalid or incomplete POST params
Started POST "/onboarding_steps/update_multiple" for ::1 at 2018-06-15 15:47:08 -0500
ActionController::RoutingError (No route matches [POST] "/onboarding_steps/update_multiple"):
_edit_multiple.html.erb
<%= form_for :onboarding_steps, :url => update_multiple_onboarding_steps_path, :html => {:method => :put} do |form| %>
...
<% @onboarding_steps.each do |onboarding_step| %>
<%= fields_for "onboarding_steps[]", onboarding_step do |f| %>
... this is where it breaks the form ...
<% if onboarding_step.onboarding_checkbox.present? %>
<%= f.fields_for :onboarding_checkbox, onboarding_step.onboarding_checkbox do |checkboxes_form| %>
<%= submit_tag "Update", :class=>"btn btn-small btn-primary" %>
onboarding_steps_controller.rb
def edit_multiple
onboarding_step = OnboardingStep.find(params[:onboarding_step_id])
@onboarding_steps = OnboardingStep.includes(:onboarding_step_type).find(onboarding_step.group_steps.ids)
end
def update_multiple
logger.debug params
params.permit!
@onboarding_steps = OnboardingStep.update(params[:onboarding_steps].keys, params[:onboarding_steps].values)
@onboarding_steps.reject! { |s| s.errors.empty? }
if @onboarding_steps.empty?
redirect_to :back, notice: 'Update Successful'
else
render "edit_multiple"
end
end
which at the bottom does include onboarding_checkbox_attributes:[]
onboarding_step.rb has accepts_nested_attributes_for :onboarding_checkbox
routes.rb
resources :onboarding_steps do
resources :onboarding_checkboxes
member do
get "delete"
end
collection do
get :edit_multiple
put :update_multiple
end
end
Not sure where it's going wrong. It's Friday and my brain is fried
Had this same issue. Got around it by using each_with_index and assign an index to the record set:
In other words, instead of doing this:
<% @onboarding_steps.each do |onboarding_step| %>
<%= fields_for "onboarding_steps[]", onboarding_step do |f| %>
do this:
<% @onboarding_steps.each_with_index do |onboarding_step, index| %>
<%= fields_for "onboarding_steps[#{index}]", onboarding_step do |f| %>
I struggled with a very similar problem for a couple hours today. I think your issue is in:
f.fields_for :onboarding_checkbox
The error message, and resulting title of this question, is very misleading due to the way Rails handles PUT and PATCH requests. It says:
Invalid or incomplete POST params
Started POST "/update_multiple_objects" for ::1 at 2023-06-26 02:53:35 -0700
ActionController::RoutingError (No route matches [POST] "/update_multiple_objects"):
The key is in the first line: "Invalid or incomplete POST params". Because most browsers don't support PUT or PATCH requests, Rails Fudges it with a post request and a hidden "_method" input tag. I bet if you go into your HTML, that _method tag will still be present in your form. The issue is that you are passing "Invalid or Incomplete POST params", which causes rails to throw the POST error, even though you are "correctly" trying a PATCH.
Now, why are your POST params invalid or incomplete? When I went to look at the HTML form output, I noted that fields_for each "onboarding_step" would be correctly coded with the ID, e.g.
<input ... name="onboarding_step[203][some_attribute]"
where "203" is the id of that object. BUT, if you look at the fields for the nested object, :onboarding_checkbox
, you will note that it is wrapped with
<input ... name="onboarding_step[][onboarding_checkbox]
The id is missing!! Eventually, I actually figured it out by looking at this Question, and I realized Rails was expecting a pluralized option, even with a belongs_to (i.e. singular) association!
In my case, when I pluralized the object in my nested fields_for, it worked! Notably, the HTML started correctly wrapping the object id in the tags. So I suggest you try:
f.fields_for :onboarding_checkboxes
instead of the singular.
PS: I know this question is very stale - just posting this answer here for future reference of anyone else who stumbles on this issue.
PPS: this may not completely solve your problem. There are nuances to trying to do this through a belongs_to relationship, and at one point it wasn't possible at all (that post contains some workarounds)! However, it should be fixed with some adaptations as of Rails 4 and 5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With