0

I have two models user and profile.
I want to save the username and password in user and other user profile details in profile.
Now,
The user model has:

has_one :profile
accepts_nested_attributes_for :profile
attr_accessible :email, :password

The profile model has

 belongs_to :user
 attr_accessible :bio, :birthday, :color

The user controller has

 def new
    @user = User.new
    @profile = @user.build_profile
  end

  def create
    @user = User.new(params[:user])
    @profile = @user.create_profile(params[:profile])
    if @user.save
      redirect_to root_url, :notice => "user created successfully!"
    else
      render "new"
    end
  end

The view new.html.erb have fields for both user and profile.
However,when I run this web application it shows error:

Can't mass-assign protected attributes: profile

on debug it stuck at @user = User.new(params[:user]) in create action

so,what is wrong? I have also tried putting :profile_attributes in attr_accessible but it doesn't help!
please help me to find out solution.

Chirag Rupani
  • 1,675
  • 1
  • 17
  • 37
  • 1
    try to remove `@profile = @user.create_profile(params[:profile])` line. You don't need it. – Vasiliy Ermolovich Aug 13 '12 at 06:28
  • It looks like that profile params which you intented to pass to @profile actually are going to user params, hence you have a problem in your user form – megas Aug 13 '12 at 06:35
  • This tells me there is something wrong with your view. Your params hash should have a `:profile_attributes` rather than `:profile` key. Mass assignment is failing because you don't have a `profile` attribute and it's not accessible. If you are calling fields_for in the view make sure to pass it the model for profile. Possibly `@profile` or `@user.profile` and not simply a string or symbol by that name. – Joeyjoejoejr Aug 13 '12 at 07:24
  • @Joeyjoejoejr , I have used Atprofile in field_for and 2all the problem is in Atuser = User.new(params[:user]) – Chirag Rupani Aug 13 '12 at 09:31
  • Yes, and your problem, as I said, is that the params returned by field_for should be in the key `profile`, they should be in the key `profile_attribures` which should be in your attr_accessible call. When you try and save, rails is looking for a profile attribute or method which doesn't exist, `profile_attributes` is added by `accepts_nested_attributes_for`. Also make sure your fields_for call is nested within a form_for call for the user model. – Joeyjoejoejr Aug 13 '12 at 14:46

1 Answers1

1

First off, as suggested by @nash, you should remove @profile = @user.create_profile(params[:profile]) from your create action. accepts_nested_attributes_for will automatically create your profile for you.

Check that your view is set up correctly for nested attributes. Should shouldn't be seeing anything in params[:profile]. The profile attributes need to come through in params[:user][:profile_attributes] for nested models to work correctly.

In summary, your create action should look like this:

def create
  @user = User.new(params[:user])

  if @user.save
    redirect_to root_url, :notice => "user created successfully!"
  else
    render "new"
  end
end

Your form view (typically _form.html.erb) should look something like this:

<%= form_for @user do |f| %>

  Email: <%= f.text_field :email %>
  Password: <%= f.password_field :password %>

  <%= f.fields_for :profile do |profile_fields| %>

    Bio: <%= profile_fields.text_field :bio %>
    Birthday: <%= profile_fields.date_select :birthday %>
    Color: <%= profile_fields.text_field :color %>

  <% end %>

  <%= f.submit "Save" %>

<% end %>

For more information, see this old but great tutorial by Ryan Daigle.

jstr
  • 1,271
  • 10
  • 17
  • using :profile doesn't show any profile fields.The problem is while creating new user it has profile attributes that are unable to mass-assigned. – Chirag Rupani Aug 13 '12 at 12:10
  • Well basically if you use `accepts_nested_attributes_for` correctly you'll never run into the mass-assignment protection issue. You really never need to use `params[:profile]` anywhere in your code. Your controllers don't even need to know UserProfile exists. I suggest you read through the tutorial by Ryan Daigle I linked to. – jstr Aug 13 '12 at 12:26