How to call a class specific method in a module

Viewed 41

I'm currently doing this

class Enrollment < ApplicationRecord
  belongs_to :user
  validate :no_conflict

  private
  def no_conflict
    user.enrollments.where.not(id: self).each do |e|
      errors.add(:start_time, 'conflicts with another schedule') if true
    end
  end
end

class Availability < ApplicationRecord
  belongs_to :user
  validate :no_conflict

  private
  def no_conflict
    user.availabilities.where.not(id: self).each do |a|
      errors.add(:start_time, 'conflicts with another schedule') if true
    end
  end
end

Since there's identical code in both models I'm trying to move it to a concern like this

class Enrollment < ApplicationRecord
  include Schedulize
end

class Availability < ApplicationRecord
  include Schedulize
end

module Schedulize
  extend ActiveSupport::Concern
    
  included do
    belongs_to :user
    validate :no_conflict
  end
    
  private
  def no_conflict
    user.<???>.where.not(id: self).each do |x|
      errors.add(:start_time, 'conflicts with another schedule') if true
    end
  end
end

I wasn't sure how to have the module call the class method that's including it (where the questions marks are above). Could someone help point me in the right direction

1 Answers

You can do something like this:

def no_conflict
  user.send(self.class.table_name).where.not(id: self).each do |x|
    errors.add(:start_time, 'conflicts with another schedule') if true
  end
end

self.class.table_name will return enrollments & availabilities as per convention. If you have different names for the relationships in model & the table names, you can try something different.

Related