Search code examples
ruby-on-railsruby-on-rails-5.2

Dynamic scope with or method in Rails 5


Some scopes of my Unit model:

class Unit < ApplicationRecord
  scope :committees,   -> { where(unit_type: UnitType.committee) }
  scope :departments,  -> { where(unit_type: UnitType.department) }
  scope :faculties,    -> { where(unit_type: UnitType.faculty) }
  scope :programs,     -> { where(unit_type: UnitType.program) }
  scope :universities, -> { where(unit_type: UnitType.university) }
end

class UnitType < ApplicationRecord
  enum group: {
    other: 0,
    university: 1,
    faculty: 2,
    department: 3,
    program: 4,
    committee: 5
  }
end

I want to create new scope with using other scopes like this:

class Unit < ApplicationRecord
  ...
  scope :for_curriculums, -> { universities.or(faculties).or(departments) }
  scope :for_group_courses, -> { faculties.or(departments) }
  ...
end

But in this way too many double-triple combinations are occurred.

When I use send parameter like following code, 'and' method is running instead of 'or' method.

class Unit < ApplicationRecord
  ...
  # unit_types = ['faculties', 'departments']
  def self.send_chain(unit_types)
    unit_types.inject(self, :send)
  end
end

How can I do, is there any possibility?


Solution

  • class Unit < ApplicationRecord
      UnitType.groups.each do |unit_type|
        scope ActiveSupport::Inflector.pluralize(unit_type), -> { 
          where(unit_type: unit_type)
        }
      end
    
      scope :by_multiple_unit_types, ->(unit_types) {
        int_unit_types =  unit_types.map { |ut| UnitType.groups.index(ut) }.join(',')
        where("unit_type IN (?)", int_unit_types)
      }
    end