Nos documentos do Rails 3 , o build
método para associações é descrito como sendo o mesmo que o new
método, mas com a atribuição automática da chave estrangeira. Diretamente dos documentos:
Firm#clients.build (similar to Client.new("firm_id" => id))
Eu li similar em outro lugar.
No entanto, quando eu uso new
(por exemplo, some_firm.clients.new
sem nenhum parâmetro), a firm_id
associação do novo cliente é criada automaticamente. Estou olhando os resultados agora no console!
Estou esquecendo de algo? Os documentos estão um pouco desatualizados (improvável)? Qual é a diferença entre build
e new
?
ruby-on-rails
ruby-on-rails-3
associations
Encerramento
fonte
fonte
Respostas:
Você está interpretando mal os documentos um pouco.
some_firm.client.new
é a criação de um novoClient
objeto da coleção clientes, e por isso pode automaticamente definir ofirm_id
quesome_firm.id
, ao passo que os documentos estão chamandoClient.new
que não tem conhecimento de ID de qualquer empresa em tudo, por isso precisa dofirm_id
passado para ele.A única diferença entre
some_firm.clients.new
esome_firm.clients.build
parece ser quebuild
também adiciona o cliente recém-criado àclients
coleção:Se você estiver criando um objeto por meio de uma associação,
build
deve ter preferência sobrenew
como a build mantém seu objeto na memóriasome_firm
(neste caso) em um estado consistente mesmo antes de qualquer objeto ter sido salvo no banco de dados.fonte
some_firm.client.new
também acrescenta que o clientesome_firm.clients
, e chamandosave
onsome_firm
resultou em um erro de validação, indicando queclient
era inválido. Se ambosnew
ebuild
adicionar o novo cliente àsome_firm
coleção de clientes, obuild
quenew
isso não faz? Sinto muito por ser densa, aqui!build
é apenas um alias paranew
:Pode encontrar o código completo: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb#L74
fonte
alias build new
a partir dos trilhos 3.2.13build
ebuild_#{association}
. Veja aqui e aqui .Rails 4
?Você está correto, a construção e as novas funções têm o mesmo efeito de definir a chave estrangeira, quando são chamadas por meio de uma associação. Acredito que a razão pela qual a documentação seja escrita dessa maneira é esclarecer que um novo objeto Cliente está sendo instanciado, em oposição a um novo relacionamento de registro ativo. Esse é o mesmo efeito que chamar .new em uma classe teria em Ruby. Ou seja, a documentação está esclarecendo que a criação de chamada em uma associação é a mesma coisa, está criando um novo objeto (chamando .new) e passando as chaves estrangeiras para esse objeto. Estes comandos são todos equivalentes:
Acredito que a razão .build existe é que Firm.first.clients.new pode ser interpretado como significando que você está criando um novo objeto has_many, em vez de um cliente real, então chamar .build é uma maneira de esclarecer isso.
fonte
build
vsnew
:por exemplo:
para novos:
Para construção:
Aqui, os clientes são armazenados na memória. Quando salvos com firmeza, os registros associados também são salvos.
fonte
Model.new
Tag.new post_id: 1
instanciará uma tag com seupost_id
conjunto.@ model.models.new
@post.tags.build
faz o mesmo E a tag instanciada estará presente@post.tags
mesmo antes de ser salva.Isso significa
@post.save
que salvará o @post e a tag recém-criada (assumindo: inverse_of está definido). Isso é ótimo porque o Rails validará os dois objetos antes de salvar e nenhum será salvo se um deles falhar na validação.models.new vs models.build
@post.tags.build
e@post.tags.new
são equivalentes (pelo menos desde o Rails 3.2).fonte
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:
?