2009-04-23 4 views
122

Non riesco a trovare alcuna documentazione sul metodo .build in Rails (sto attualmente utilizzando 2.0.2).Ruby on Rails. Come utilizzare il metodo Active Record .build in a: appartiene alla relazione?

Attraverso la sperimentazione sembra possibile utilizzare il metodo di compilazione per aggiungere un record in una relazione has_many prima che uno dei due record sia stato salvato.

Ad esempio:

class Dog < ActiveRecord::Base 
    has_many :tags 
    belongs_to :person 
end 

class Person < ActiveRecord::Base 
    has_many :dogs 
end 

# rails c 
d = Dog.new 
d.tags.build(:number => "123456") 
d.save # => true 

Ciò farà risparmiare sia il cane e tag con le chiavi esterne correttamente. Non sembra funzionare in una relazione belongs_to.

d = Dog.new 
d.person.build # => nil object on nil.build 

ho anche provato

d = Dog.new 
d.person = Person.new 
d.save # => true 

La chiave esterna in Dog non è impostato in questo caso dovuto al fatto che al momento in cui viene salvata, la nuova persona non ha un id perché non è stato ancora salvato.

Le mie domande sono:

  1. Come si fa a costruire lavoro in modo che Rails è abbastanza intelligente per capire come salvare i record nel giusto ordine?

  2. Come posso fare la stessa cosa in una relazione belongs_to?

  3. Dove è possibile trovare documentazione su questo metodo?

Grazie

+0

Per quanto riguarda la documentazione, vedere le Guide Rails [_ "metodi aggiunti da' belongs_to'" _] (http://guides.rubyonrails.org/association_basics.html#methods-added-by-belongs-to) e [_ "Metodi aggiunti da' has_one' "_] (http://guides.rubyonrails.org/association_basics.html#methods-added-by-has-one). Più documentazione tecnica può essere trovata nei documenti API: ['belongs_to'] (http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to) e [' has_one'] (http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_one). – Dennis

risposta

140

Dove è documentato:

Dalla documentazione API nell'ambito dell'associazione has_many in "Module ActiveRecord::Associations::ClassMethods"

collection.build (attributi = {}, ... Restituisce uno o più nuovi oggetti del tipo di raccolta che sono stati istanziati con attributi e collegato a questo oggetto tramite una chiave esterna , ma non è stato ancora salvato . Nota: funziona solo se esiste già un oggetto associato , non se è nullo!

La risposta alla costruzione nella direzione opposta è una sintassi leggermente modificata. Nel tuo esempio con i cani,

Class Dog 
    has_many :tags 
    belongs_to :person 
end 

Class Person 
    has_many :dogs 
end 

d = Dog.new 
d.build_person(:attributes => "go", :here => "like normal") 

o anche

t = Tag.new 
t.build_dog(:name => "Rover", :breed => "Maltese") 

È inoltre possibile utilizzare create_dog di averlo salvato immediatamente (molto simile al corrispondente metodo di "creare" si può chiamare sulla raccolta)

In che modo le rotaie sono abbastanza intelligenti? È magico (o più esattamente, non lo so, mi piacerebbe scoprirlo!)

+4

@BushyMark: usa method_missing o metaporgramming per aggiungere quei metodi con define_method. – Federico

+0

@Federico dove è definito il metodo mancante? – efoo

+1

@ alock27 Uguale al modo in cui ActiveRecord utilizza il metodo mancante per i metodi 'find_by_email' e' find_by_column_name'. Converte il metodo passato a una stringa e lo seziona e prova a farlo corrispondere ai nomi delle colonne della tabella. – Edmund

40
@article = user.articles.build(:title => "MainTitle") 
@article.save 
+0

>> d.tags.build (: number => "123456") >> d.save # => true Non il stesso? – antiqe