En los documentos de Rails 3 , el build
método para las asociaciones se describe como el mismo que el new
método, pero con la asignación automática de la clave externa. Directamente de los documentos:
Firm#clients.build (similar to Client.new("firm_id" => id))
He leído similares en otros lugares.
Sin embargo, cuando uso new
(por ejemplo, some_firm.clients.new
sin ningún parámetro), la firm_id
asociación del nuevo cliente se crea automáticamente. ¡Estoy mirando los resultados ahora mismo en la consola!
¿Me estoy perdiendo de algo? ¿Los documentos están un poco desactualizados (poco probable)? ¿Cuál es la diferencia entre build
y new
?
ruby-on-rails
ruby-on-rails-3
associations
Cierre Vaquero
fuente
fuente
Respuestas:
Estás leyendo mal los documentos un poco.
some_firm.client.new
está creando un nuevoClient
objeto de la colección de clientes y, por lo tanto, puede establecerlo automáticamentefirm_id
ensome_firm.id
, mientras que los documentos están llamandoClient.new
y no tienen ningún conocimiento de la identificación de ninguna empresa, por lo que necesitafirm_id
pasarla.La única diferencia entre
some_firm.clients.new
ysome_firm.clients.build
parece ser quebuild
también agrega el cliente recién creado a laclients
colección:Si está creando un objeto a través de una asociación,
build
debe preferirse anew
que build mantenga su objeto en memoriasome_firm
(en este caso) en un estado coherente incluso antes de que los objetos se hayan guardado en la base de datos.fuente
some_firm.client.new
también añade que el clientesome_firm.clients
, y llamandosave
ensome_firm
dio lugar a un error de validación que indica queclient
no era válido. Si ambosnew
ybuild
agregan el nuevo cliente asome_firm
la colección de clientes, ¿qué hacebuild
eso quenew
no hace? Lo siento por ser denso, aquí!build
es solo un alias paranew
:Se puede encontrar el código completo: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb#L74
fuente
alias build new
a partir de rieles 3.2.13build
ybuild_#{association}
. Mira aquí y aquí .Rails 4
?Tiene razón, la compilación y las nuevas funciones tienen el mismo efecto de establecer la clave foránea, cuando se llaman a través de una asociación. Creo que la razón por la cual la documentación está escrita de esta manera es para aclarar que se está instanciando un nuevo objeto Cliente, en lugar de una nueva relación de registro activa. Este es el mismo efecto que tendría llamar a .new en una clase en Ruby. Es decir que la documentación aclara que llamar a construir en una asociación es lo mismo que crear un nuevo objeto (llamar a .new) y pasar las claves foráneas a ese objeto. Estos comandos son todos equivalentes:
Creo que la razón por la que existe .build es que Firm.first.clients.new podría interpretarse en el sentido de que está creando un nuevo objeto de relación has_many, en lugar de un cliente real, por lo que llamar a .build es una forma de aclarar esto.
fuente
build
vsnew
:p.ej:
para nuevo:
Para construir:
Aquí los clientes se almacenan en la memoria, cuando se guardan firmes, los registros asociados también se guardan.
fuente
Modelo nuevo
Tag.new post_id: 1
instanciará una etiqueta con supost_id
conjunto.@ model.models.new
@post.tags.build
hace lo mismo Y la etiqueta instanciada estará@post.tags
incluso antes de que se guarde.Esto significa
@post.save
que guardará tanto la etiqueta @post como la recién creada (suponiendo que se establezca inverse_of). Esto es genial porque Rails validará ambos objetos antes de guardarlos, y ninguno se guardará si alguno de ellos falla la validación.models.new vs models.build
@post.tags.build
y@post.tags.new
son equivalentes (al menos desde Rails 3.2).fuente
The only difference between some_firm.clients.new and some_firm.clients.build seems to be that build also adds the newly-created client to the clients collection:
?