The usual way to build a relation in a ActiveSupport::Concern Show archive.org snapshot is this:
module MyModule
  extend ActiveSupport::Concern
  included do
    scope :disabled, -> { where(disabled: true) }
  end
end
However, if you have a association with a polymorphic model, where you have to select based on the kind of record, using included like this will not produce the wanted results:
module MyModule
  extend ActiveSupport::Concern
  included do
    has_many :tasks,
      -> { where concrete_mission_type: self.class.name },
      foreign_key: :mission_id,
      inverse_of: :mission
  end
end
> mission.tasks.to_sql
"SELECT \"tasks\".* FROM \"tasks\" WHERE \"tasks\".\"mission_id\" = 735 AND \"tasks\".\"concrete_mission_type\" = 'ActiveRecord::Relation'"
You can fix that through using self.included(subclass) in your concern:
module MyModule
  extend ActiveSupport::Concern
  def self.included(subclass)
    subclass.class_eval do
      has_many :tasks,
        -> { where concrete_mission_type: subclass.name },
        foreign_key: :mission_id,
        inverse_of: :mission
    end
    super
  end
end
> mission.tasks.to_sql
"SELECT \"tasks\".* FROM \"tasks\" WHERE \"tasks\".\"mission_id\" = 737 AND \"tasks\".\"concrete_mission_type\" = 'ConspirationFinder'"
If you want to know more about self.included, see this card.
Posted by Judith Roth to makandra dev (2021-04-30 13:06)