我设置了一个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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top