添加各种模型的关注范围

Add scope in concerns for various models

在apps/models/concerns/deactivable.rb

module Deactivatable
  extend ActiveSupport::Concern

  included do
    scope :alive, -> { where(:deactivated_at => nil) }
  end

  def deactivate(t = Time.current)
    update_attribute(:deactivated_at,t)
  end

  def activate
    update_attribute(:deactivated_at,nil)
  end

  def deactivated?
    deactivated_at.present?
  end

end

这包括在 2 个模型中,app/models/activity_rules/activity_detection_rule.rb 和 app/models/concerns/generic_campaign.rb.

还有 2 个模型包含相同的方法,但属性名称不同。

在redeemable.rb,

class Redeemable < ActiveRecord::Base
  scope :alive, -> { where("(deactivation_date is null) and (expiry_date is null or expiry_date >= ?)",Date.today) }

  def deactivate(t = Time.current)
    update_attribute(:deactivation_date,t)
  end

  def reactivate
    update_attribute(:deactivation_date,nil)
  end

  def deactivated?
    deactivation_date.present?
  end
end

并在 surprise_set.rb

scope :alive, -> { where("deactivation_date is null") }

使用与redeemable.rb相同的3种方法。

如何使用Deactivable concern来DRY另外两个模型?

您可以 return 指示 class 方法停用时间的属性。如果需要,您可以在关注中提供默认实现并在包含关注的 class 中覆盖:

module Deactivatable
  extend ActiveSupport::Concern

  included do
    scope :alive, -> { where(deactive_attr => nil) }

    def self.deactive_attr
      :deactivated_at
    end
  end

  def deactivate(t = Time.current)
    update_attribute(self.class.deactive_attr, t)
  end

  def activate
    update_attribute(self.class.deactive_attr, nil)
  end

  def deactivated?
    self.send(self.class.deactive_attr).present?
  end

end

然后,在 classes 中您想提供不同的属性,您可以添加 class 方法:

include Deactivatable

def self.deactive_attr
  :deactivation_date
end

您还可以通过允许包含关注点的 class 为 'aliveness' 定义条件,从而使您的 alive 范围变干一点。在关注中你可以定义默认值

scope :alive, -> { where(self.active_conditions) }

def self.active_conditions
  { self.deactive_attr => nil }
end

然后您可以在 class 本身中提供 active_conditions 的不同实现:

self self.active_conditions
  ["(deactivation_date is null) and 
   (expiry_date is null or expiry_date >= ?)", Date.today]
end