Search code examples
ruby-on-railsrubyactiverecordruby-on-rails-5

Rails ActiveRecord - Applying a condition or scope to multiple associations


Suppose we have the following relations:

class Users < ActiveRecord::Base
  has_many :meetings
  has_many :events
end

class Meetings < ActiveRecord::Base
  scope :is_morning_meeting, -> { where.some.condition }
end

class Events < ActiveRecord::Base
  scope :is_morning_event, -> { where.some.condition }
end

Is there a way for me to grab entire User object, but specify the is_morning_* scope across these associations.

Something like:

class Users < ActiveRecord::Base
  has_many :meetings, -> () { is_morning_meeting if scope.morning_concerns }
  has_many :events, -> () { is_morning_event if scope.morning_concerns }

  scope :morning_concerns
end

used like so:

morning_user = user.morning_concerns

And if I call

morning_user.meetings

it should only return morning meetings

and if I call

morning_user.events

it should only return morning events

This might seem a bit specific, but I'm finding myself cornered here because of a GraphQL resolve flow.


Solution

  • You can define a custom has_many associations with a scope like this:

    class Users < ActiveRecord::Base
      has_many :meetings
      has_many :morning_meetings, -> { is_morning_meeting }, class_name: "Meeting"
      has_many :events
      has_many :morning_events, -> { is_morning_event }, class_name: "Event"
    end
    

    And can simply call those associations like normal associations:

    user.morning_meetings
    user.morning_events