É necessário verificar se um bloco de atributos foi alterado antes da atualização no Rails 3.
street1, street2, cidade, estado, código postal
Eu sei que eu poderia usar algo como
if @user.street1 != params[:user][:street1]
then do something....
end
Mas esse pedaço de código será REALMENTE longo. Existe uma maneira mais limpa?
Foi assim que resolvi o problema de verificar alterações em vários atributos.
O
changed
método retorna uma matriz dos atributos alterados para esse objeto.Ambos
@user.changed
eattrs
são matrizes para que eu possa obter a interseção (consulte oary & other ary
método). O resultado da interseção é uma matriz. Ao chamarany?
a matriz, sou verdadeiro se houver pelo menos uma interseção.Também muito útil, o
changed_attributes
método retorna um hash dos atributos com seus valores originais echanges
retorna um hash dos atributos com seus valores originais e novos (em uma matriz).Você pode verificar o APIDock para quais versões suportam esses métodos.
http://apidock.com/rails/ActiveModel/Dirty
fonte
if attrs.any?{|attr| @user.send("#{attr}_changed?")}
Quando quero verificar se um dos vários atributos diferentes foi alterado - Obviamente, só faço isso com os atributos que me defini, porque não gosto de usar parâmetros de usuário em umsend
método. ;)ActiveModel::Dirty
não funcionou para mim porque@model.update_attributes()
ocultou as alterações. Então é assim que eu detectei as alterações em umupdate
método em um controlador:Se você está tentando detectar muitas alterações de atributo, pode ficar confuso. Provavelmente não deveria fazer isso em um controlador, mas meh.
fonte
previous_changes
que também está disponível por padrão.#update_attributes
não oculta as alterações. Ele salva o registro, para que o modelo seja atualizado e não haja alterações. Você precisa alterar o campo no modelo e verificarchanged?
antes de salvá-lo. ie @ model.field = 'foo' ou@model.attributes = @model.attributes.merge(params[:model])
Para trilhos 5.1 + retornos de chamada
A partir do Ruby on Rails 5.1, os métodos
attribute_changed?
eattribute_was
ActiveRecord serão descontinuadosUse em
saved_change_to_attribute?
vez deattribute_changed?
Mais exemplos aqui
fonte
As respostas acima são melhores, mas, para conhecimento, também temos outra abordagem: o valor da coluna 'categoria' permite que um objeto seja alterado (@design),
As alterações. Retornarão um hash com a chave como nome da coluna e os valores como uma matriz com dois valores [old_value, new_value] para cada coluna. Por exemplo, a categoria acima é alterada de 'ABC' para 'XYZ' de @design,
Para alteração de referências no ROR
fonte