2

Trying to figure out why the setter doesn't work on:

class Company < ActiveRecord::Base
  has_many :memberships 
  has_many :users, :through => :memberships, dependent: :destroy

end

class Membership < ActiveRecord::Base
  belongs_to :user
  belongs_to :company

  validates_presence_of :user
  validates_presence_of :company

end

class User < ActiveRecord::Base
  has_many :memberships
  has_many :companies, :through => :memberships, dependent: :destroy
  accepts_nested_attributes_for :companies
end

<%= form_for(@user) do |f| %>
  <% if @user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
      <% @user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.fields_for :company do |ff|%>
      <%= ff.label :name %><br>
      <%= ff.text_field :name %>
    <% end %>
  </div>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

# Never trust parameters from the scary internet, only allow the white list through.
def user_params
  params.require(:user).permit(:name, companies_attributes:[:name])
end

it works when I do:

# Never trust parameters from the scary internet, only allow the white list through.
def user_params
  params.require(:user).permit(:name, company:[:name])
end

So for me it's not quite clear as the documentation says the setter companies_attributes is ceated when accepts_nested_attributes_for :companies

Paul Richter
  • 10,908
  • 10
  • 52
  • 85
gtheys
  • 501
  • 3
  • 19

1 Answers1

2

When using fields_for with accepts_nested_attributes_for they need to match. see http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for

you have accepts_nested_attributes_for :companies but f.fields_for :company hence the disconnect.

So try changing your form to include

<div class="field">
    <%= f.fields_for :companies do |ff|%>
      <%= ff.label :name %><br>
      <%= ff.text_field :name %>
    <% end %>
  </div>

and your user_params method to be

def user_params
  params.require(:user).permit(:name, companies_attributes:[:name])
end

Which should cause them to be populated under companies_attributes and your original user_params method to work. as the fields_for should generate user[companies_attributes[id][name]] since user has_many companies (do you want to include multiple companies in the list to be created?)

Doon
  • 19,719
  • 3
  • 40
  • 44
  • Well I used the logs :) But still didn't get it... Parameters: {"utf8"=>"✓", "authenticity_token"=>"p08a+oGeMwhECryeQfDyO3th1lLarapkXKQtKb15nWZnD5kGU6o5zJLdTVlBmKK99dpmI4Pczap188P+Uuvqkw==", "user"=>{"company"=>{"name"=>"fff"}, "name"=>"ffff"}, "commit"=>"Create User"} Unpermitted parameter: company "user_params {\"name\"=>\"ffff\"}" Unpermitted parameter: company – gtheys Dec 30 '14 at 15:26
  • 1
    :companies doesn't generate a form field for company.name – gtheys Dec 30 '14 at 15:28
  • See the other part of my answer about changing the fields for to match association/accepts_nested_attributes_for. – Doon Dec 30 '14 at 15:30
  • 1
    it is a has_many , so it should generate it for user[companies_attributes[id][name]] – Doon Dec 30 '14 at 15:31
  • also my answer applies to just a `has_many`, since it is for the `has_many :through` check out this answer as it might help more http://stackoverflow.com/questions/21983131/rails-4-nested-attributes-and-has-many-through-associaton-in-a-form – Doon Dec 30 '14 at 15:43