Para atribuição em massa de valores a um modelo ActiveRecord sem salvar, use os métodos assign_attributes
ou attributes=
. Esses métodos estão disponíveis no Rails 3 e mais recentes. No entanto, existem pequenas diferenças e dicas relacionadas à versão a serem observadas.
Ambos os métodos seguem esse uso:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }
@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }
Observe que nenhum dos métodos realizará validações ou executará retornos de chamada; retornos de chamada e validação acontecerão quando save
for chamado.
Trilhos 3
attributes=
difere um pouco do assign_attributes
Rails 3. attributes=
irá verificar se o argumento passado para ele é um Hash e retorna imediatamente se não for; assign_attributes
não tem essa verificação de hash. Consulte a documentação da API ActiveRecord Attribute Assignment paraattributes=
.
O seguinte código inválido falhará silenciosamente retornando sem definir os atributos:
@user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]
attributes=
comportará silenciosamente como se as designações tivessem sido feitas com sucesso, quando na verdade não eram.
Este código inválido gerará uma exceção ao assign_attributes
tentar especificar as chaves hash da matriz anexa:
@user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ])
assign_attributes
irá gerar uma NoMethodError
exceção para stringify_keys
, indicando que o primeiro argumento não é um Hash. A exceção em si não é muito informativa sobre a causa real, mas o fato de ocorrer uma exceção é muito importante.
A única diferença entre esses casos é o método usado para atribuição em massa: attributes=
silenciosamente é bem-sucedido e assign_attributes
gera uma exceção para informar que ocorreu um erro.
Esses exemplos podem parecer inventados, e são até certo ponto, mas esse tipo de erro pode ocorrer facilmente ao converter dados de uma API, ou mesmo usando uma série de transformação de dados e esquecendo Hash[]
os resultados da final .map
. Mantenha algum código de 50 linhas acima e 3 funções removidas da atribuição de atributo, e você terá uma receita para a falha.
A lição do Rails 3 é esta: sempre use em assign_attributes
vez de attributes=
.
Trilhos 4
No Rails 4, attributes=
é simplesmente um apelido para assign_attributes
. Consulte a documentação da API ActiveRecord Attribute Assignment paraattributes=
.
Com o Rails 4, qualquer um dos métodos pode ser usado de forma intercambiável. A falha em passar um Hash como o primeiro argumento resultará em uma exceção muito útil:ArgumentError: When assigning attributes, you must pass a hash as an argument.
Validações
Se você estiver executando tarefas de pré-vôo em preparação para a save
, também poderá estar interessado em validar antes de salvar. Você pode usar os métodos valid?
e invalid?
para isso. Ambos retornam valores booleanos. valid?
retorna true se o modelo não salvo passa em todas as validações ou false se não passa. invalid?
é simplesmente o inverso devalid?
valid?
pode ser usado assim:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?
Isso permitirá que você lide com qualquer problema de validação antes de ligar save
.