Reputation: 5693
I've checked a few answers to similar problems, and all seem to suggest the problem is attr_accessible, but I just can't seem to get this working.
Basically I have User & Address model,and want to assign Address attributes as nested attributes. But when I save it causes the can't mass-assign attributes error shown below.
I've tried many variations of attr_accessible in below code, like :addresses_attributes, :address_attributes, :primary_address_attributes...I'm not sure why it's not working,perhaps because it's in the Member module declaration??
Can anyone help?
class Member::User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# each user may have zero or many addresses
# their primary email is also set as their login id.
has_many :addresses
has_one :address, :class_name => "Member::Address", :conditions => "is_primary = true"
accepts_nested_attributes_for :addresses, :address
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :address_attributes
validates_presence_of :email
end
My form that submits the nested fields (relevant parts of)
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:class => "form-horizontal"}) do |f| %>
<small>Mandatory fields marked *</small><br><br>
<% devise_error_messages! %>
<% flash.each do |name, msg| %>
<div class="alert alert-<%= name == :notice ? "success" : "error" %>">
<a class="close" data-dismiss="alert">×</a>
<%= msg %>
</div>
<% end %>
<%= f.fields_for resource.build_primary_address do |address_form| %>
<div class="control-group">
<%= address_form.label :first_name, :class => "control-label" %>
<div class="controls">
<%= address_form.text_field :first_name, :class => "input-xlarge" %>
</div>
</div>
<div class="control-group">
<%= address_form.label :last_name, :class => "control-label" %>
<div class="controls">
<%= address_form.text_field :last_name, :class => "input-xlarge" %>
</div>
</div>
<% end %>
The error shows this:
Can't mass-assign protected attributes: member_address
{"utf8"=>"✓",
"authenticity_token"=>"HrZJG2krn15veUKJVh6PgEs4wwufaeRhciHcUIn6AaM=",
"user"=>{"member_address"=>{"first_name"=>"asdf",
"last_name"=>"asdfsafd"},
"email"=>"[email protected]",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"}}
Upvotes: 0
Views: 297
Reputation: 8892
In order for rails to understand that that the primary address being submitted in the form is a nested attribute, you have to explicitly tell it the relation here:
<%= f.fields_for :address, resource.build_primary_address do |address_form| %>
. The reason is, because your model names are scoped with Member::
, and rails derives form parameter names from the class names, in your params hash you end up with :member_address instead of :address. Because :address in this case is a field for which :user accepts nested attributes, :address should be represented as :address_attributes in the params hash, so make sure the latter appears in attr_accessible.
Upvotes: 1
Reputation: 15788
Add
attr_accessible :member_address
to the User model.
Explanation: every hash key that you want to initialize an ActiveRecord instance with must be stated as attr_accessible. Looking at your hash keys there is:
"user"=>{"member_address"=>{ ... }}
member_address key in the hash which initializes the User instance, thus it has to be included in the attr_accessible statement.
Upvotes: 0