在Rails的after_save回调中确定哪些属性发生了变化?

9 浏览
0 Comments

在Rails的after_save回调中确定哪些属性发生了变化?

我正在设置一个模型观察器中的after_save回调函数,只有当模型的published属性从false变为true时才发送通知。由于像changed?这样的方法只在模型保存之前有用,所以我目前(且不成功地)尝试的方法如下:\n

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

\n有没有人对如何处理这个问题有任何建议,最好使用模型观察器回调函数(以避免污染我的控制器代码)?

0
0 Comments

在Rails中,有一个after_save回调,用于在保存记录之后执行某些操作。在这个回调中,可能会使用attribute_changed?方法来确定属性是否发生了更改,以及使用attribute_change方法来获取属性的变化前后的值。

然而,在Rails 5.1版本中,ActiveModel::Dirty类发生了一些变化,导致在after回调中使用attribute_changed?和attribute_change方法会产生警告。这个警告指出,在下一个版本的Rails中,这两个方法的返回值将会改变,以反映在保存之后调用这两个方法的行为。

为了解决这个问题,可以将attribute_changed?方法替换为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来代替。

总之,如果在Rails的after_save回调中使用了attribute_changed?和attribute_change方法,在Rails 5.1版本及以上,会出现警告,建议使用saved_change_to_attribute?和saved_change_to_attribute方法来替代。这个改变是为了更好地反映方法在调用save之后的行为。

0
0 Comments

在Rails的after_save回调中,想要知道刚刚所做的更改,可以使用以下方法:

Rails 5.1及更高版本

model.saved_changes

Rails < 5.1

model.previous_changes

这些方法在你不想使用模型回调并且需要在进行进一步功能之前进行有效保存时非常有效。

在我的测试中(Rails 4),如果你使用的是after_save回调,self.changed?trueself.attribute_name_changed?也为true,但self.previous_changes返回一个空的哈希。

看起来previous_changes是Rails 5的一个函数。你可以在Rails 4中实现这个功能,方法是在before_save调用中添加一个attr_accessor :previous_change,然后在after_save中再次访问它。

在Rails 4.2中也适用:devdocs.io/rails~4.2/activemodel/…

在Rails 5.1及更高版本中,这个方法已经被弃用。请在after_save回调中使用saved_changes代替。

0
0 Comments

在Rails中,有一个after_save回调方法,可以在记录保存之后执行一些操作。在这个例子中,我们想要确定在after_save回调中更改了哪些属性。

在Rails 5.1+中,可以使用saved_change_to_attribute?方法来确定属性是否已更改。在下面的代码中,我们在after_update回调中使用saved_change_to_published?方法来检查是否已更改了published属性并且其值为true:

class SomeModel < ActiveRecord::Base
  after_update :send_notification_after_change
  def send_notification_after_change
    Notification.send(...) if (saved_change_to_published? && self.published == true)
  end
end

在Rails 3-5.1中,我们可以使用属性名_changed?方法来确定属性是否已更改。在下面的代码中,我们在after_update回调中使用self.published_changed?方法来检查是否已更改了published属性并且其值为true:

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

总结一下,我们可以通过saved_change_to_attribute?或属性名_changed?方法来确定属性是否在after_save回调中更改。这是两个不同版本的Rails中的解决方法。

0