2010-08-17 15 views
8

J'ai une relation de type parent et enfant. Dans la migration.rb de l'enfant, les colonnes du modèle enfant ont chacune des valeurs par défaut (à l'exception de la colonne parent_id).Ruby on Rails: Construction d'un enfant avec des valeurs par défaut lorsque son parent est créé

Lorsque je crée un nouvel objet parent, comment puis-je faire en sorte qu'un objet enfant soit créé et enregistré dans sa table avec les données des valeurs par défaut avec le parent_id?

Je pense que cela aura à voir avec quelque chose comme un after_create sur le modèle parent, mais je ne sais pas comment le configurer.

Répondre

12

Révision: J'ai révisé la réponse à utiliser avant de créer et de créer, sans créer, les modèles associés. La machine ActiveRecord prend alors soin d'enregistrer les modèles associés une fois le parent enregistré.

J'ai même testé ce code!

# in your Room model... 
has_many :doors 

before_create :build_main_door 

private 

def build_main_door 
    # Build main door instance. Will use default params. One param (:main) is 
    # set explicitly. The foreign key to the owning Room model is set 
    doors.build(:main => true) 
    true # Always return true in callbacks as the normal 'continue' state 
end 

####### has_one case: 

# in your Room model... 
has_one :door 
before_create :build_main_door 
private 
def build_main_door 
    # Build main door instance. Will use default params. One param (:main) is 
    # set explicitly. The foreign key to the owning Room model is set 
    build_door(:main => true) 
    true # Always return true in callbacks as the normal 'continue' state 
end 

... Ajouté

La méthode de construction est ajoutée par les machines du modèle possédante par la déclaration has_many. Puisque l'exemple utilise has_many: doors (nom du modèle Door), l'appel de construction est doors.build

Voir les docs for has_many et has_one pour voir toutes les méthodes supplémentaires qui sont ajoutées.

# If the owning model has 
has_many :user_infos # note: use plural form 

# then use 
user_infos.build(...) # note: use plural form 

# If the owning model has 
has_one :user_info  # note: use singular form 

# then use 
build_user_info(...) # note: different form of build is added by has_one since 
        # has_one refers to a single object, not to an 
        # array-like object (eg user_infos) that can be 
        # augmented with a build method 

Rails 2.x a introduit l'option d'enregistrement automatique pour les associations. Je ne pense pas que cela s'applique à ce qui précède (j'utilise par défaut). Autosave testing results.

+0

Le modèle enfant dans mon exemple est appelé "user_info", quand j'essaie de faire user_info.create (: main => true) 'il erreurs et dit' undefined méthode \ 'créer 'pour nil: NilClass' – Reti

+0

en fait, le modèle est techniquement appelé' userInfo' – Reti

+0

Essayez 'UserInfo.create' – zetetic

0

Vous n'avez pas spécifié (ou je l'ai ignoré) le type de relation que vous utilisez. Si vous utilisez une relation un-à-un, telle que "has_one", créez ne fonctionnera pas. Dans ce cas, vous devez utiliser quelque chose comme ceci:

dans parent.rb

has_one :child 
before_create {|parent| parent.build_child(self)} 

after_create pourrait fonctionner aussi bien, havent testé cela.

tandis que dans child.rb

belongs_to :parent 

je luttais avec ce tout à fait un peu lors de la mise en place d'un modèle utilisateur dans mon application en cours.

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html Vous pouvez voir que has_one ne supporte pas parent.build ou parent.create

Hope this helps. Im nouveau à Ruby moi-même et commence lentement à faire mon chemin à travers la jungle Ruby. Un bon voyage, mais facile à se perdre. :)