Estou configurando um retorno de chamada after_save no meu observador de modelo para enviar uma notificação apenas se o atributo publicado do modelo tiver sido alterado de falso para verdadeiro. Desde métodos como mudou? são úteis apenas antes de o modelo ser salvo, da maneira que estou tentando (e sem êxito) atualmente é o seguinte:
def before_save(blog)
@og_published = blog.published?
end
def after_save(blog)
if @og_published == false and blog.published? == true
Notification.send(...)
end
end
Alguém tem alguma sugestão sobre a melhor maneira de lidar com isso, de preferência usando retornos de chamada de observador de modelo (para não poluir meu código de controlador)?
fonte
after_update
chamada:after_update :send_notification_after_change, if: -> { published_changed? }
saved_change_to_published?
ousaved_change_to_published
buscar a alteração durante o retorno de chamadaPara quem deseja saber as alterações feitas apenas em um
after_save
retorno de chamada:Trilhos 5.1 e superior
Trilhos <5,1
Consulte também: http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-previous_changes
fonte
after_save
retorno de chamada,self.changed?
étrue
eself.attribute_name_changed?
é tambémtrue
, masself.previous_changes
retorna um hash vazio.saved_changes
Emafter_save
vez disso, use em retornos de chamadaPara quem vê isso mais tarde, como atualmente (agosto de 2017) supera o google: vale a pena mencionar, que esse comportamento será alterado no Rails 5.2 e possui avisos de descontinuação no Rails 5.1, pois o ActiveModel :: Dirty mudou um pouco .
O que eu mudo?
Se você estiver usando o
attribute_changed?
método nosafter_*
callbacks, verá um aviso como:Como ele menciona, você pode corrigir isso facilmente, substituindo a função por
saved_change_to_attribute?
. Então, por exemplo,name_changed?
torna-sesaved_change_to_name?
.Da mesma forma, se você estiver usando o
attribute_change
para obter os valores antes e depois, isso também muda e gera o seguinte:Novamente, como mencionado, o método altera o nome para o
saved_change_to_attribute
qual retorna["old", "new"]
. ou usesaved_changes
, que retorna todas as alterações, e essas podem ser acessadas comosaved_changes['attribute']
.fonte
attribute_was
métodos: use emsaved_change_to_attribute
vez disso.Caso você possa fazer isso em
before_save
vez deafter_save
, poderá usar isso:retorna uma matriz de todas as colunas alteradas nesse registro.
você também pode usar:
que retorna um hash de colunas que foram alteradas e os resultados anteriores e posteriores como matrizes
fonte
after_
retorno de chamada, que é sobre o que a questão realmente era. A resposta de @ jacek-głodek abaixo é a correta.before_save
self.changed
pode ser usado emafter_save
retornos de chamada.self.changed
é uma matriz de strings! (Não é um símbolo!) #["attr_name", "other_attr_name"]
A resposta "selecionada" não funcionou para mim. Estou usando o rails 3.1 com CouchRest :: Model (baseado no modelo ativo). Os
_changed?
métodos não retornam true para atributos alterados noafter_update
gancho, apenas nobefore_update
gancho. Consegui fazê-lo funcionar usando oaround_update
gancho (novo?) :fonte
você pode adicionar uma condição
after_update
semelhante à seguinte:não há necessidade de adicionar uma condição no
send_notification
próprio método.fonte
Você acabou de adicionar um acessador que define o que você altera
fonte