ruby-on-rails-5nested-formsstrong-parametersfields-for

Rails5, unpermitted params in nested form, while associating existing objects


Why why why...?

Three models (FirstModel, SecondModel, JoinedModel), JoinedModel belongs to both others and other two has_many of each other, through JoinedModel. JoinedModel accepts_nested_attributes_for first_model and second_model.

It also validates presence of first_model_id and second_model_id.

Joined model strong params:

private
 def joined_params
   params.require(:joined_model).permit(:first_model_id, :second_model_id,
                  :first_models_attributes => [:id, :name],
                  :second_models_attributes => [:id, :full_name])
 end

JoinedModel's _form:

<%= form_for(joined_model) do |f| %>
 <%= f.fields_for :second_models do |ff| %>
  <%= ff.select(SecondModel.all.map {|c| [ c.full_name, c.id ] }, { include_blank: true }) -%>

(and the same f.fields_for for FirstModel)

When I submit this form, I get

Unpermitted params first_models, second_models

And query:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"gvW/OrOXJruAK0ZD+uoajJ4N+dZvpmZF8Ay0TOKF9HPO19d4tRBoWz0C4VoaOABYat8KzrryL8lp5ax+Y9ZJRg==", "joined_model"=>{"first_models"=>{"first_model_id"=>"1"}, "second_models"=>{"second_model_id"=>"1"}}, "commit"=>"Create Joined model"}

I dont know why, how etc. form tries to send a hash - "second_models"=>{"second_model_id"=>"1"} it supposed to be just like "second_model_id"=>"1" and it does like this if my form uses simple f.number_field :first_model_id instead of select...


Solution

  • I found the answer and will leave this post, since many similar unanswered questions found on StackOverflow

    So, the answer was to use parent's fields builder for select, like:

    <%= form_for(joined_model) do |f| %>
     <%= f.fields_for :second_models do |ff| %>
      <%= f.select(SecondModel.all.map {|c| [ c.full_name, c.id ] }, { include_blank: true }) -%>
    

    Looks like it works all fine now, but if anyone knows why I even need to provide builder object (in my case |ff|) for nested fields if I am not even using it, I will give a Hi Five and a Tango dance!

    UPDATE:

    So I found that in this situation I didn't even needed fields_for... Now it all makes sence, since here I was creating a new JoinedModel's record and only selecting other two (existing) records and association simply lets me grab those methods... Bit lame, but oh well...