2009-04-23 7 views
122

J'ai été incapable de trouver de la documentation sur la méthode. Build dans Rails (j'utilise actuellement la version 2.0.2). Par expérimentation, il semble que vous pouvez utiliser la méthode build pour ajouter un enregistrement dans une relation has_many avant que l'enregistrement ait été sauvegardé.Ruby on Rails. Comment puis-je utiliser la méthode Active Record .build dans un: appartient à la relation?

Par exemple:

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 

Cela permettra d'économiser à la fois le chien et l'étiquette avec les clés étrangères correctement. Cela ne semble pas fonctionner dans une relation belongs_to.

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

J'ai aussi essayé

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

La clé étrangère dans Dog n'est pas réglé dans ce cas en raison du fait que, au moment où il est enregistré, la personne n'a pas d'identité parce que il n'a pas encore été enregistré.

Mes questions sont les suivantes:

  1. Comment construire le travail de sorte que Rails est assez intelligent pour savoir comment sauvegarder les enregistrements dans l'ordre? Comment faire la même chose dans une relation belongs_to?

  2. Où puis-je trouver une documentation sur cette méthode?

Merci

+0

En ce qui concerne la documentation, consultez les guides Rails [_ "__gVirt_NP_NNS_NNPS<__ méthodes ajoutées par' belongs_to'" _] (http://guides.rubyonrails.org/association_basics.html#methods-added-by-belongs-to) et [_ "Méthodes ajoutées par' has_one' "_] (http://guides.rubyonrails.org/association_basics.html#methods-added-by-has-one). Une documentation plus technique peut être trouvée dans les documents API: ['belongs_to'] (http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to) et [' has_one'] (http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_one). – Dennis

Répondre

140

Lorsqu'il est documenté:

De la documentation API dans l'association has_many dans "Module ActiveRecord::Associations::ClassMethods"

collection.build (attributs = {}, ... Renvoie un ou plusieurs nouveaux objets du type de collection qui ont été instanciés avec des attributs et lié à cet objet via une clé étrangère , mais n'a pas encore été enregistré en . Note: Ceci ne fonctionne que si un objet associé existe déjà, pas s'il est nul!

La réponse à la construction dans la direction opposée est une syntaxe légèrement modifiée. Dans votre exemple, avec les chiens,

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") 

ou même

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

Vous pouvez également utiliser create_dog pour avoir sauvé instantanément (un peu comme la méthode « créer » correspondant, vous pouvez faire appel à la collection)

Comment les rails sont-ils assez intelligents? C'est magique (ou plus exactement, je ne sais pas, je serais ravi de le découvrir!)

+4

@BushyMark: il utilise method_missing ou metaporgramming pour ajouter ces méthodes avec define_method. – Federico

+0

@Federico où la méthode manquante est-elle définie? – efoo

+1

@ alock27 Identique à la méthode utilisée par ActiveRecord pour vos méthodes 'find_by_email' et' find_by_column_name'. Il convertit la méthode que vous passez en une chaîne et la dissèque et essaie de la faire correspondre avec les noms de colonne de votre table. – Edmund

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

>> d.tags.build (: number => "123456") >> d.save # => true même? – antiqe

Questions connexes