ruby-on-rails 如何检测模型中的属性变化?

w6mmgewl  于 2023-08-08  发布在  Ruby
关注(0)|答案(6)|浏览(131)

我想在rails中创建一个回调函数,在模型保存后执行。
我有这样一个模型,Claim有一个属性'status',它根据Claim的状态而变化,可能的值是pending,endorsed,approved,rejected
数据库的“state”默认值为“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

字符串
我的问题是如何检查模型中更改之前的值?

ohfgkhjo

ohfgkhjo1#

你应该看看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"]}

字符串

huwehgph

huwehgph2#

你可以用这个

self.changed

字符串
它返回一个包含该记录中所有更改列的数组
你也可以使用

self.changes


它返回改变的列的哈希值以及结果前后的数组

i2loujxw

i2loujxw3#

对于Rails 5.1+,您应该使用活动记录属性方法:是否已将更改保存为属性?

是否已将更改保存为属性?(属性名称,**选项)'

上次储存时,此属性是否有变更?这个方法可以叫用为saved_change_to_name?,而非saved_change_to_attribute?("name")。行为类似于attribute_changed?。这个方法在回调之后很有用,以确定调用保存是否改变了某个属性。

选项

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

guykilcj

guykilcj4#

我建议您看看可用的状态机插件之一:

任何一个都可以让您设置状态和状态之间的转换。非常有用和简单的方式来处理您的要求。

hyrbngr7

hyrbngr75#

我看到这个问题在很多地方出现过,所以我为此写了一个小小的rubygem,让代码更好一些(避免到处出现一百万条if/else语句):https://github.com/ronna-s/on_change希望有帮助。

ozxc1zmp

ozxc1zmp6#

如果您使用经过良好测试的解决方案,例如state_machine gem,您会更好。

相关问题