确定Rails中被改变的属性after_save的回调?
-
27-09-2019 - |
题
我设置了一个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
滤波器在模型上你的可以使用_changed?
存取(至少在导轨3,不能确定为Rails 2)。因此,例如:
class SomeModel < ActiveRecord::Base
after_update :send_notification_after_change
def send_notification_after_change
Notification.send(...) if (self.published_changed? && self.published == true)
end
end
这只是工作。
其他提示
对于那些想知道谁只是在after_save
回调所做的更改:
的Rails 5.1和更高的
model.saved_changes
滑轨<5.1
model.previous_changes
另请参见: http://api.rubyonrails.org /classes/ActiveModel/Dirty.html#method-i-previous_changes
要任何人看到这个以后,因为它目前(8月2017)上衣谷歌:值得一提的是,这种行为将被改变中的的Rails 5.2 ,并具有废弃警告,如钢轨5.1,如 ::加载ActiveModel脏的改变了一点。
我该怎么改变?
如果您正在使用attribute_changed?
方法在after_*
-回调,你会看到这样的警告:
弃用警告:回调之后将在导轨的下一个版本被改变
attribute_changed?
内的行为。新的返回值将反映在调用该方法的行为后save
返回(例如什么现在返回对面)。为了保持当前的行为,使用saved_change_to_attribute?
代替。 (从/PATH_TO/app/models/user.rb:15 some_callback称为)
作为它提到,你可以很容易通过用saved_change_to_attribute?
替换功能解决这个问题。因此,例如,name_changed?
变得saved_change_to_name?
。
同样的,如果你使用的attribute_change
拿到前,后的值,这个变化也并引发以下内容:
弃用警告:回调之后将在导轨的下一个版本被改变
attribute_change
内的行为。新的返回值将反映在调用该方法的行为后save
返回(例如什么现在返回对面)。为了保持当前的行为,使用saved_change_to_attribute
代替。 (从/PATH_TO/app/models/user.rb:20 some_callback称为)
再次,因为它提到,该方法改变名称saved_change_to_attribute
返回["old", "new"]
。
或使用saved_changes
,它返回所有的变化,并且这些可以作为saved_changes['attribute']
被访问。
在情况下,你可以在before_save
代替after_save
做到这一点,你就可以使用这样的:
self.changed
它返回在该记录中的所有改变列的阵列。
还可以使用:
self.changes
,它返回改变之前和结果阵列后列的哈希
在“选择”的回答并没有为我工作。我使用的钢轨3.1 CouchRest ::模型(基于Active模式)。该_changed?
方法不要在after_update
钩更改的属性返回true,只有在before_update
钩。我使用(?新)around_update
钩能得到它的工作:
class SomeModel < ActiveRecord::Base
around_update :send_notification_after_change
def send_notification_after_change
should_send_it = self.published_changed? && self.published == true
yield
Notification.send(...) if should_send_it
end
end
可以添加条件,像这样after_update
:
class SomeModel < ActiveRecord::Base
after_update :send_notification, if: :published_changed?
...
end
有没有必要向send_notification
方法本身内添加条件。
我正在使用此来提取与新的属性值的散列,这是有用的用于我更新其他模型
attributes_changed = self.changes.inject(Hash.new){|hash,attr| ((hash[attr[0].to_sym] = attr[1].last) || attr[1].last == false) && hash}
在
attr[1].last == false
时,当新的值是false
,其中所述分配返回false和“散列”不返回必要的。
我想有一个更简单的方法,我是新来的轨道
您只需添加谁定义你改变什么的访问
class Post < AR::Base
attr_reader :what_changed
before_filter :what_changed?
def what_changed?
@what_changed = changes || []
end
after_filter :action_on_changes
def action_on_changes
@what_changed.each do |change|
p change
end
end
end