Search code examples
ruby-on-railsactiverecordmodulerakemixins

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


I have (I think) the reverse of this question.

I have a module (ActiveConcern) that is normally included in some ActiveRecord models:

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

Now I am writing a rake task that needs to call this 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

The error thrown is:

undefined method `before_save' for Object:Class

In the context of the rake task, the before_save callback does not make sense (and in fact throws the error as that method does not exist here, since it's not an ActiveRecord model, just a PORO).

Obviously I could remove the included code from the module and add the before_save callback to every class that includes the module.

But I am hoping an easier solution would be to add a condition to the included so that before_save is only added to ActiveRecord models. Is that even possible...something like:

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

Solution

  • You are calling calculate_score in the context of contact the include of IntegretyScoring is not needed.