Getting fields for and accepts zagnieżdżone atrybuty for to work with a belongs to relation

Nie mogę uzyskać zagnieżdżonego formularza do wygenerowania w widoku rails dla relacji belongs_to przy użyciu nowego obiektu accepts_nested_attributes_for w Rails 2.3. Sprawdziłem wiele dostępnych zasobów i wygląda na to, że mój kod powinien działać, ale fields_for eksploduje na mnie i podejrzewam, że ma to coś wspólnego z konfiguracją zagnieżdżonych modeli.

Błąd, który trafiłem jest częstym, który może mieć wiele przyczyn:

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

Oto dwa modele zaangażowany:

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

Być może tutaj robię to 'rong' , ponieważ konto może mieć 'właściciela', a może 'użytkowników' , ale użytkownik ma tylko jedno 'konto', oparte na kluczu account_id modelu użytkownika.

To jest kod widoku w new.html.haml to mnie rozwala:

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

A to jest kod kontrolera dla nowej akcji:

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

Kiedy próbuję załadować / konto / nowe, dostaję następujący wyjątek:

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

Jeśli spróbuję użyć tajemniczej metody 'build', to po prostu bomby w kontrolerze, być może dlatego, że build jest tylko dla relacji multi-record:

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

Jeśli spróbuję to skonfigurować używając @ account.owner_attributes = {} w kontrolerze lub @ account.właściciel = użytkownik.nowy, wracam do oryginalnego błędu, "@ konto [właściciel] nie jest dozwolone jako nazwa zmiennej instancji".

Czy ktoś jeszcze ma nową metodę accepts_nested_attributes_for działającą z relacją belongs_to? Czy jest coś wyjątkowego lub innego, co musisz zrobić? Wszystkie oficjalne przykłady i przykładowy kod (Jak the great stuff over at Ryans Scraps ) dotyczy skojarzeń z wieloma płytami.

Author: Billy Gray, 2009-08-21

4 answers

Myślę, że twój związek jest po złej stronie. Może coś takiego zadziała?

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

Do budowania konta, którego chcesz użyć build_account.

Więcej przykładów można znaleźć w docs.
 8
Author: Andy Gaskell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-07 07:53:50

Jestem o kilka miesięcy za późno, ale chciałem rozwiązać ten błąd i Moja sytuacja była taka, że nie mogę zmienić relacji ,aby "zmierzyć się w drugą stronę".

Odpowiedź naprawdę jest dość prosta, musisz to zrobić w swojej nowej akcji:

@account.build_owner

Powodem, dla którego formularz nie wyświetlał się przy użyciu fields_for, było to, że nie posiadał poprawnego obiektu. Miałeś tam dobry pomysł:

@account.owner.build

Jednak tak nie działa belongs_to. Ta metoda jest generowana tylko z has_many i has_and_belongs_to_many.

Odniesienie: http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference

 44
Author: Jaryl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-16 10:37:51

Używam Rails 2.3.5 i zauważyłem to samo. Sprawdzanie źródła nested_attributes active_record.rb, wygląda na to, że belongs_to powinno działać dobrze. Wygląda na to, że może to być błąd "zagnieżdżonych formularzy".

Mam zagnieżdżoną formę dokładnie taką jak Twoja, z User belongs_to :address i {[1] } jest niezależna od użytkownika.

Następnie w formie, po prostu zrobić <% f.fields_for :address_attributes do |address_form| %> zamiast <% f.fields_for :address do |address_form| %>. Tymczasowe włamanie, dopóki nie będzie lepszego sposobu, ale to działa. Metoda accepts_nested_attributes_for spodziewa się, że paramy zawierają coś w stylu:

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

...ale fields_for produkuje:

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

W ten sposób nie musisz dodawać tego has_one :account do swojego kodu, co nie działa w moim przypadku.

Aktualizacja: znalazłem lepszą odpowiedź:

Oto treść kodu, którego używam do poprawnego działania:

Rails zagnieżdżone formy z belongs_to Gist

Mam nadzieję, że to pomoże.
 8
Author: Lance Pollard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-13 23:06:54
class Account < ActiveRecord::Base

    belongs_to :owner  :class_name => 'User', :foreign_key => 'owner_id'
end
U mnie działa. :foreign_key = > 'owner_id' był kluczowym problemem w moim przypadku.
 -3
Author: Zdenek.paclik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-19 14:52:48