Я настраиваю обратный вызов after_save в моем обозревателе модели для отправки уведомления, только если атрибут публикации модели был изменен с false на true. Так как методы, такие как изменились? полезны только перед сохранением модели, так как я сейчас (и безуспешно) пытаюсь сделать это следующим образом:
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
У кого-нибудь есть какие-либо предложения относительно лучшего способа справиться с этим, предпочтительно с помощью обратных вызовов наблюдателя модели (чтобы не загрязнять код моего контроллера)?
after_update
вызову:after_update :send_notification_after_change, if: -> { published_changed? }
saved_change_to_published?
илиsaved_change_to_published
получить изменения во время обратного вызоваДля тех, кто хочет знать изменения, сделанные только что в
after_save
обратном вызове:Rails 5.1 и выше
Рельсы <5.1
Также см .: http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-previous_changes
источник
after_save
обратный вызов,self.changed?
естьtrue
иself.attribute_name_changed?
естьtrue
, ноself.previous_changes
возвращает пустой хеш.saved_changes
вafter_save
обратныхЛюбой, кто увидит это позже, так как он в настоящее время (август 2017 г.) возглавляет Google: стоит упомянуть, что это поведение будет изменено в Rails 5.2 и имеет предупреждения об устаревании, начиная с Rails 5.1, как ActiveModel :: Dirty немного изменилась ,
Что я могу изменить?
Если вы используете
attribute_changed?
метод вafter_*
-callbacks, вы увидите предупреждение вроде:Как уже упоминалось, вы можете легко это исправить, заменив функцию на
saved_change_to_attribute?
. Так, например,name_changed?
становитсяsaved_change_to_name?
.Аналогично, если вы используете
attribute_change
для получения значений до и после, это также изменяется и выдает следующее:Опять же, как упоминалось, метод меняет имя, на
saved_change_to_attribute
которое возвращается["old", "new"]
. или используйтеsaved_changes
, который возвращает все изменения, и к ним можно получить доступ какsaved_changes['attribute']
.источник
attribute_was
методов: используйтеsaved_change_to_attribute
вместо этого.Если вы можете сделать это
before_save
вместоafter_save
, вы сможете использовать это:он возвращает массив всех измененных столбцов в этой записи.
Вы также можете использовать:
который возвращает хэш столбцов, которые изменились и до и после результатов в виде массивов
источник
after_
обратном вызове, о чем на самом деле и был вопрос. Ответ @ jacek-głodek ниже является правильным.before_save
self.changed
могут использоватьсяafter_save
обратные вызовы.self.changed
является массив строк! (Не символы!)["attr_name", "other_attr_name"]
«Выбранный» ответ не работал для меня. Я использую рельсы 3.1 с CouchRest :: Model (на основе Active Model). Эти
_changed?
методы не возвращают верно для измененных атрибутов вafter_update
крючке, только вbefore_update
крюке. Я смог заставить его работать, используя (новый?)around_update
Хук:источник
Вы можете добавить условие к
after_update
так:нет необходимости добавлять условие в сам
send_notification
метод.источник
Вы просто добавляете аксессор, который определяет, что вы меняете
источник