Получение fields_for и accepts_nested_attributes_for для работы с принадлежащим отношением - PullRequest
28 голосов
/ 21 августа 2009

Я не могу получить вложенную форму для генерации в представлении rails для отношения belongs_to с использованием нового средства accepts_nested_attributes_for Rails 2.3. Я проверил многие из доступных ресурсов, и похоже, что мой код должен работать, но fields_for взрывает меня, и я подозреваю, что это как-то связано с тем, как я настроил вложенные модели .

Ошибка, с которой я столкнулся, является распространенной и может иметь много причин:

'@account[owner]' is not allowed as an instance variable name

Вот две модели:

class Account < ActiveRecord::Base
  # Relationships
  belongs_to :owner, :class_name => 'User', :foreign_key => 'owner_id'
  accepts_nested_attributes_for :owner
  has_many :users
end

class User < ActiveRecord::Base
  belongs_to :account
end

Возможно, именно здесь я делаю это «rong», поскольку у учетной записи может быть «владелец», а может и «пользователи», но у пользователя есть только одна «учетная запись», основанная на ключе account_id модели пользователя.

Это код вида в new.html.haml, который взрывает меня:

- form_for :account, :url => account_path do |account|
  = account.text_field :name
  - account.fields_for :owner do |owner|
    = owner.text_field :name

А это код контроллера для нового действия:

class AccountsController < ApplicationController
  # GET /account/new
  def new
    @account  = Account.new
  end
end

Когда я пытаюсь загрузить / account / new, я получаю следующее исключение:

NameError in Accounts#new
Showing app/views/accounts/new.html.haml where line #63 raised:
@account[owner] is not allowed as an instance variable name

Если я пытаюсь использовать таинственный метод «сборки», он просто взрывается в контроллере, возможно, потому что сборка предназначена только для отношений с несколькими записями:

class AccountsController < ApplicationController
  # GET /account/new
  def new
    @account  = Account.new
    @account.owner.build
  end
end

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.build

Если я попытаюсь установить это с помощью @ account.owner_attributes = {} в контроллере или @ account.owner = User.new, я вернусь к исходной ошибке: «@account [owner] не разрешен как имя переменной экземпляра ".

Кто-нибудь еще имеет новый метод accepts_nested_attributes_for, работающий с отношением own_to? Есть что-то особенное или другое, что вы должны сделать? Все официальные примеры и примеры кода (например, замечательные материалы на Ryans Scraps ) касаются ассоциаций с несколькими записями.

Ответы [ 4 ]

44 голосов
/ 14 марта 2010

Я опоздал на несколько месяцев, но я пытался решить эту ошибку, и моя ситуация заключалась в том, что я не мог изменить отношения, чтобы «встретить другое».

Ответ действительно очень прост, вы должны сделать это в вашем новом действии:

@account.build_owner

Причина, по которой форма не отображалась с использованием fields_for, заключалась в том, что у нее не было допустимого объекта. У вас была правильная идея:

@account.owner.build

Тем не менее, belongs_to не работает. Этот метод генерируется только с has_many и has_and_belongs_to_many.

Справка: http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference

8 голосов
/ 13 января 2010

Я использую Rails 2.3.5 и заметил то же самое. Проверяя источник для nested_attributes.rb active_record, он выглядит так, как будто он должен работать нормально. Похоже, это может быть ошибка «вложенных форм».

У меня есть вложенная форма, точно такая же, как ваша, с User belongs_to :address, а Address не зависит от пользователя.

Тогда в форме я просто делаю <% f.fields_for :address_attributes do |address_form| %> вместо <% f.fields_for :address do |address_form| %>. Временный взлом, пока нет лучшего способа, но это работает. Метод accepts_nested_attributes_for предполагает, что параметры будут содержать что-то вроде:

{user=>{address_attributes=>{attr1=>'one',attr2=>'two'}, name=>'myname'}

... но fields_for производит:

{user=>{address=>{attr1=>'one',attr2=>'two'}, name=>'myname'}

Таким образом, вам не нужно добавлять это has_one :account в ваш код, что не работает в моем случае.

Обновление: найден лучший ответ:

Вот суть кода, который я использую для правильной работы:

Вложенные в Rails формы с принадлежностью Gist

Надеюсь, это поможет.

8 голосов
/ 21 августа 2009

Я думаю, что ваш accepts_nested_attributes находится на неправильной стороне отношений. Может быть, что-то подобное будет работать?

class Account < ActiveRecord::Base
  belongs_to :owner, :class_name => 'User', :foreign_key => 'owner_id'
  has_many :users
end

class User < ActiveRecord::Base
  belongs_to :account
  has_one :account, :foreign_key => :owner_id
  accepts_nested_attributes_for :account
end

Для создания учетной записи вы хотите использовать build_account.

Вы можете увидеть больше примеров в документах .

0 голосов
/ 19 августа 2010
class Account < ActiveRecord::Base

    belongs_to :owner  :class_name => 'User', :foreign_key => 'owner_id'
end

Это работает для меня. : foreign_key => 'owner_id' была ключевой проблемой в моем случае.

...