我想在rails中创建一个回调函数,该函数在保存模型后执行.
我有这个模型,声明具有属性'status',该属性根据声明的状态而变化,可能的值是待定,认可,批准,拒绝
数据库具有"状态",默认值为"pending".
我想在第一次创建模型后执行某些任务,或者从一个状态更新到另一个状态,具体取决于它从哪个状态更改.
我的想法是在模型中有一个功能:
    after_save :check_state
    def check_state
      # if status changed from nil to pending (created)
      do this
      # if status changed from pending to approved
      performthistask
     end
我的问题是如何在模型中更改之前检查先前的值?
Har*_*tty 170
您应该查看ActiveModel :: Dirty模块:您应该能够对您的Claim模型执行以下操作:
claim.status_changed?  # returns true if 'status' attribute has changed
claim.status_was       # returns the previous value of 'status' attribute
claim.status_change    # => ['old value', 'new value'] returns the old and 
                       # new value for 'status' attribute
claim.name = 'Bob'
claim.changed # => ["name"]
claim.changes # => {"name" => ["Bill", "Bob"]}
哦! Rails的乐趣!
zea*_*uss 37
你可以用它
self.changed
它返回在此记录中更改的所有列的数组
你也可以用
self.changes
它返回一个已更改的列的散列,以及作为数组的结果之前和之后
对于Rails 5.1+,您应该使用活动记录属性方法:saved_change_to_attribute?
已保存更改至属性?(attr_name, **选项)`
当我们上次保存时这个属性是否改变了?可以调用此方法来
saved_change_to_name?代替saved_change_to_attribute?("name")。行为类似于attribute_changed?. 此方法在回调后确定调用 save 是否更改了某个属性时很有用。选项
from传递时,此方法将返回 false,除非原始值等于给定选项
to传递时,此方法将返回 false,除非该值更改为给定值
因此,如果您想根据属性值的变化调用某些方法,您的模型将如下所示:
class Claim < ApplicationRecord
  
  after_save :do_this, if: Proc.new { saved_change_to_status?(from: nil, to: 'pending') }
  after_save :do_that, if: Proc.new { saved_change_to_status?(from: 'pending', to: 'approved') }
  
  def do_this
    ..
    ..
  end
  def do_that
    ..
    ..
  end
end
如果您不想检查回调中的值更改,您可以执行以下操作:
class Claim < ApplicationRecord
  after_save: :do_this, if: saved_change_to_status?
  def do_this
    ..
    ..
  end
end
| 归档时间: | 
 | 
| 查看次数: | 65482 次 | 
| 最近记录: |