2010-08-17 18 views
8

Tengo una relación de modelo primario y secundario. En migration.rb del elemento secundario, las columnas del modelo secundario tienen valores predeterminados (excepto la columna parent_id).Ruby on Rails: creación de un elemento secundario con valores predeterminados cuando se crea su elemento primario

Cuando hago un nuevo objeto principal, ¿cómo puedo hacerlo para que se cree un objeto hijo y se guarde en su tabla con los datos de los valores predeterminados junto con el parent_id?

Estoy pensando que tendrá que ver con algo así como un after_create en el modelo principal, pero no estoy seguro de cómo configurarlo.

Respuesta

12

Revisado: Revisé la respuesta para usar before_create y compilar, no crear, los modelos asociados. La maquinaria ActiveRecord se encarga de guardar los modelos asociados una vez que se guarda el padre.

¡Incluso probé este código!

# 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 

Agregado ...

El método de aumento es añadido por la maquinaria del modelo propietaria por la declaración has_many. Dado que el ejemplo utiliza has_many: puertas (nombre de modelo Puerta), la llamada de compilación es doors.build

Consulte docs for has_many y has_one para ver todos los métodos adicionales que se agregan.

# 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 introdujo la opción de autoguardado para las asociaciones. No creo que se aplique a lo anterior (estoy usando el valor predeterminado). Autosave testing results.

+0

El modelo hijo en mi ejemplo se llama "user_info", cuando intento hacer 'user_info.create (: main => true)' comete un error y dice 'undefined método \ 'crear 'para nil: NilClass' – Reti

+0

en realidad, el modelo se llama técnicamente' userInfo' – Reti

+0

Pruebe 'UserInfo.create' – zetetic

0

No especificó (o lo superé) el tipo de relación que está utilizando. Si está utilizando una relación de uno a uno, como "has_one", crear no funcionará. En este caso hay que usar algo como esto:

en parent.rb

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

after_create podría funcionar tan bien, que havent probado.

mientras que en child.rb

belongs_to :parent 

he tenido problemas con esta un poco cuando la creación de un modelo de usuario en mi aplicación actual.

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html Se puede ver que has_one no soporta parent.build o parent.create

Espero que esto ayude. Soy nuevo para Ruby y lentamente empiezo a abrirme camino a través de la jungla Ruby. Un buen viaje pero fácil de perderse :) :)

Cuestiones relacionadas