设置特定对象字段后30分钟后运行作业

时间:2018-03-21 13:33:15

标签: ruby-on-rails ruby-on-rails-5 jobs

我需要运行一个作业,在设置名为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。那么有什么解决方案如何在设置字段后运行作业?谢谢。

2 个答案:

答案 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检查列值的更改。请务必仔细阅读文档,因为有很多问题。