我需要运行一个作业,在设置名为published_at
的比赛字段时向用户发送电子邮件。所以我有一个Contest
模型和一个运行工作的方法:
class Contest < ApplicationRecord
after_create :send_contest
private
def send_contest
SendContestJob.set(wait: 30.minutes).perform_later(self)
end
end
但即使published_at
字段为空,作业也会运行。验证要存在的字段不是一个选项,因为稍后可以设置published_at
。那么有什么解决方案如何在设置字段后运行作业?谢谢。
答案 0 :(得分:6)
ActiveModel::Dirty在这里可能很有用。有了它,您可以检查哪些字段即将更改/已更改:
person.name # => "bob"
person.name = 'robert'
person.save
person.previous_changes # => {"name" => ["bob", "robert"]}
因此,如果published_at_changed?
返回true,则安排工作。
答案 1 :(得分:3)
您可以使用针对新记录和现有记录触发的after_create
,而不是使用before_save
。
if:
和unless:
选项允许您指定要调用回调所需的条件,您可以传递Proc,Lambda或要调用的方法的名称。
class Contest < ApplicationRecord
before_save :send_contest, if: -> { published_at.present? && published_at_changed? }
# or
before_save :send_contest, if: :publishable?
private
def send_contest
SendContestJob.set(wait: 30.minutes).perform_later(self)
end
def publishable?
published_at.present? && published_at_changed?
end
end
根据Sergio Tulentsev的建议,您可以使用ActiveRecord::Dirty检查列值的更改。请务必仔细阅读文档,因为有很多问题。