Rals 5.2 - 如何为模块设置条件?

Rals 5.2 - how to set conditions on included for a module?

我有(我认为) 的反面。

我有一个通常包含在某些 ActiveRecord 模型中的模块 (ActiveConcern):

module IntegrityScoring
  extend ActiveSupport::Concern

  included do
    before_save :calculate_score, if: :has_changes_to_save?
  end

  def calculate_score
    # do some work
  end
end

现在我正在写一个rake任务需要调用这个calculate_score:

  task seed_weights: :environment do    
    include IntegrityScoring # * this line throws an error *

    Contact.all.each do |contact|
      contact.score = contact.calculate_score
      contact.save
    end
  end

抛出的错误是:

undefined method `before_save' for Object:Class

在 rake 任务的上下文中,before_save 回调没有意义(实际上抛出错误,因为这里不存在该方法,因为它不是 ActiveRecord 模型,只是一个 PORO) .

显然我可以从模块中删除 included 代码并将 before_save 回调添加到包含该模块的每个 class。

但我希望更简单的解决方案是向 included 添加条件,以便 before_save 仅添加到 ActiveRecord 模型。这甚至有可能......类似:

  included 'only if including class is type of ActiveRecord' do
    before_save :calculate_score, if: :has_changes_to_save?
  end

我认为你应该能够跳过回调

Contact.skip_callback(:save, :before, : calculate_score, raise: false))

您在联系人上下文中调用 calculate_score,不需要包含 IntegretyScoring。