Chirag Rupani
Chirag Rupani

Reputation: 1715

Nested model in Rails3

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.

Upvotes: 0

Views: 88

Answers (1)

jstr
jstr

Reputation: 1281

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.

Upvotes: 1

Related Questions