Вложенная модель в Rails3

У меня есть две модели: пользователь и профиль.
Я хочу сохранить имя пользователя и пароль в файле user и другие данные профиля пользователя в профиле.
Теперь
Модель пользователя имеет:

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

Модель профиля имеет

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

Пользовательский контроллер имеет

 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

В представлении new.html.erb есть поля как для пользователя, так и для профиля.
Однако, когда я запускаю это веб-приложение, появляется ошибка:

Невозможно массово назначить защищенные атрибуты : profile

при отладке застрял на @user = User.new(params[:user]) в действии создания

Итак, что не так? Я также пытался поместить :profile_attributes в attr_accessible, но это не помогает!
пожалуйста, помогите мне найти решение.


person Chirag Rupani    schedule 13.08.2012    source источник
comment
попробуйте удалить @profile = @user.create_profile(params[:profile]) строку. Вам это не нужно.   -  person Vasiliy Ermolovich    schedule 13.08.2012
comment
Похоже, что параметры профиля, которые вы намеревались передать в @profile, на самом деле переходят в пользовательские параметры, поэтому у вас есть проблема в вашей пользовательской форме.   -  person megas    schedule 13.08.2012
comment
Это говорит мне, что что-то не так с вашим мнением. Ваш хэш params должен иметь ключ :profile_attributes, а не :profile. Массовое назначение не выполняется, потому что у вас нет атрибута profile и он недоступен. Если вы вызываете fields_for в представлении, обязательно передайте ему модель для профиля. Возможно, @profile или @user.profile, а не просто строка или символ с этим именем.   -  person Joeyjoejoejr    schedule 13.08.2012
comment
@Joeyjoejoejr, я использовал Atprofile в field_for, и 2 вся проблема в Atuser = User.new(params[:user])   -  person Chirag Rupani    schedule 13.08.2012
comment
Да, и ваша проблема, как я уже сказал, заключается в том, что параметры, возвращаемые field_for, должны быть в ключе profile, они должны быть в ключе profile_attribures, который должен быть в вашем вызове attr_accessible. Когда вы пытаетесь сохранить, rails ищет несуществующий атрибут или метод профиля, profile_attributes добавляется accepts_nested_attributes_for. Также убедитесь, что ваш вызов fields_for вложен в вызов form_for для пользовательской модели.   -  person Joeyjoejoejr    schedule 13.08.2012


Ответы (1)


Прежде всего, как предложил @nash, вы должны удалить @profile = @user.create_profile(params[:profile]) из своего действия create. accepts_nested_attributes_for автоматически создаст для вас ваш профиль.

Убедитесь, что ваше представление правильно настроено для вложенных атрибутов. В params[:profile] ничего не должно быть видно. Атрибуты профиля должны пройти в params[:user][:profile_attributes] для правильной работы вложенных моделей.

Таким образом, ваше действие create должно выглядеть так:

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

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

Ваше представление формы (обычно _form.html.erb) должно выглядеть примерно так:

<%= 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 %>

Для получения дополнительной информации см. это старое, но отличное руководство Райана Дейгла.

person jstr    schedule 13.08.2012
comment
использование :profile не показывает никаких полей профиля. Проблема заключается в том, что при создании нового пользователя у него есть атрибуты профиля, которые не могут быть назначены массово. - person Chirag Rupani; 13.08.2012
comment
Ну, в принципе, если вы используете accepts_nested_attributes_for правильно, вы никогда не столкнетесь с проблемой защиты от массового назначения. Вам действительно никогда не нужно использовать params[:profile] где-либо в вашем коде. Вашим контроллерам даже не нужно знать, что UserProfile существует. Я предлагаю вам прочитать учебник Райана Дейгла, на который я ссылаюсь. - person jstr; 13.08.2012