Ottenere fields_for e accept_nested_attributes_for per lavorare con una relazione belongs_to

Non riesco a ottenere un modulo nidificato da generare in una visualizzazione delle rotaie per una relazione belongs_to utilizzando la nuova funzione accepts_nested_attributes_for di Rails 2.3. Ho controllato molte delle risorse disponibili e sembra che il mio codice dovrebbe funzionare, ma fields_for esplode su di me e ho il sospetto che abbia qualcosa a che fare con il modo in cui ho configurato i modelli nidificati.

L’errore che ho colpito è comune e può avere molte cause:

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

Ecco i due modelli coinvolti:

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

Forse è qui che lo faccio ‘rong’, in quanto un Account può avere un ‘proprietario’ e può ‘utenti’, ma un utente ha solo un ‘account’, basato sulla chiave account_id del modello utente.

Questo è il codice di vista in new.html.haml che esplode su di me:

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

E questo è il codice del controller per la nuova azione:

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

Quando provo a caricare / account / new ottengo la seguente eccezione:

 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 

Se provo a usare il misterioso metodo “build”, si tratta solo di bombe nel controller, forse perché la build è solo per le relazioni 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 

Se provo a configurarlo usando @ account.owner_attributes = {} nel controller, o @ account.owner = User.new, torno all’errore originale, “@account [owner] non è consentito come istanza nome variabile “.

Qualcun altro ha il nuovo accept_nested_attributes_for metodo che funziona con una relazione belongs_to? C’è qualcosa di speciale o diverso che devi fare? Tutti gli esempi ufficiali e il codice di esempio (come le grandi cose su Ryans Scrap ) riguardano le associazioni multi-record.

Penso che il tuo accepts_nested_attributes sia dalla parte sbagliata della relazione. Forse qualcosa del genere funzionerebbe?

 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 

Per creare l’account che desideri utilizzare build_account.

Puoi vedere altri esempi nei documenti .

Sono in ritardo di alcuni mesi, ma stavo cercando di risolvere questo errore e la mia situazione era che non potevo cambiare la relazione con “affrontare l’altra via”.

La risposta è davvero semplice, devi farlo nella tua nuova azione:

 @account.build_owner 

Il motivo per cui il modulo non è stato visualizzato utilizzando fields_for era perché non aveva un object valido. Hai avuto l’idea giusta lassù con:

 @account.owner.build 

Tuttavia, questo non è il modo in cui belongs_to lavoro. Questo metodo viene generato solo con has_many e has_and_belongs_to_many .

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

Sto usando Rails 2.3.5 e ho notato la stessa cosa. Controllando la fonte per active_record’s nested_attributes.rb, sembra che belong_to dovrebbe funzionare bene. Quindi sembra che potrebbe essere un bug “forms annidate”.

Ho un modulo annidato esattamente come il tuo, con User belongs_to :address e Address è indipendente dall’utente.

Poi nel modulo, faccio solo <% f.fields_for :address_attributes do |address_form| %> <% f.fields_for :address_attributes do |address_form| %> invece di <% f.fields_for :address do |address_form| %> <% f.fields_for :address do |address_form| %> . Temporanea modifica fino a quando non c’è un modo migliore, ma funziona. Il metodo accepts_nested_attributes_for si aspetta che i parametri includano qualcosa come:

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

… ma fields_for sta producendo:

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

In questo modo non devi aggiungere che has_one :account al tuo codice, che non funziona nel mio caso.

Aggiornamento: trovata una risposta migliore:

Ecco l’essenza del codice che sto usando per fare in modo che funzioni bene:

Rails Nested Forms with belongs_to Gist

Spero possa aiutare.

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

Per me funziona. : foreign_key => ‘owner_id’ era il problema chiave nel mio caso.