En los documentos de Rails 3 , el buildmétodo para las asociaciones se describe como el mismo que el newmé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.newsin ningún parámetro), la firm_idasociació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 buildy 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.newestá creando un nuevoClientobjeto de la colección de clientes y, por lo tanto, puede establecerlo automáticamentefirm_idensome_firm.id, mientras que los documentos están llamandoClient.newy no tienen ningún conocimiento de la identificación de ninguna empresa, por lo que necesitafirm_idpasarla.La única diferencia entre
some_firm.clients.newysome_firm.clients.buildparece ser quebuildtambién agrega el cliente recién creado a laclientscolección:Si está creando un objeto a través de una asociación,
builddebe preferirse anewque 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.newtambién añade que el clientesome_firm.clients, y llamandosaveensome_firmdio lugar a un error de validación que indica queclientno era válido. Si ambosnewybuildagregan el nuevo cliente asome_firmla colección de clientes, ¿qué hacebuildeso quenewno hace? Lo siento por ser denso, aquí!buildes 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 newa partir de rieles 3.2.13buildybuild_#{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
buildvsnew: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: 1instanciará una etiqueta con supost_idconjunto.@ model.models.new
@post.tags.buildhace lo mismo Y la etiqueta instanciada estará@post.tagsincluso antes de que se guarde.Esto significa
@post.saveque 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.buildy@post.tags.newson 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:?