Home > Enterprise >  How to use scope in an association relation
How to use scope in an association relation

Time:01-13

Background

  1. I have User
  2. I have Event
  3. User can attend many Events
  4. I have an EventUser "through" table.
  5. I have an association called :events_attending on the User model.
  6. I have past and future scopes on Event

What I'm trying to achieve

I want to be able to split the events a user is attending/has attended using syntax similar to below - whatever the correct equivalent is.

current_user.events_attending.past

But I understand that I cannot, because events_attending is an association, and even then, my understanding is that it's an association to EventUser, and not Event. So the scope still couldn't be applied.

How can I manage this such that I can do something like what I've shown in that line of code above?

Helpful source code

Event.rb:

class Event < ApplicationRecord    
    scope :future, -> { where("time > datetime()") }
    scope :past, -> { where("time < datetime()") }

    has_many :event_user
    has_many :attendees, through: :event_user, source: :user
    belongs_to :author, class_name: "User", foreign_key: "user_id"
end

User.rb

class User < ApplicationRecord
  has_many :events
  has_many :events_attending, class_name: "EventUser"
end

EventUser.rb

class EventUser < ApplicationRecord
    belongs_to :user 
    belongs_to :event
end

I removed things like devise traits and validations, for brevity.

I appreciate your time, thanks.

CodePudding user response:

Can you try setting your Event.rb class and User.rb class this way and see if it works?

class Event < ApplicationRecord    
    scope :future, -> { where("time > datetime()") }
    scope :past, -> { where("time < datetime()") }

    has_many :event_users # Note that this needs to be plural
    has_many :attendees, through: :event_user, source: :user
    belongs_to :author, class_name: "User", foreign_key: "user_id"
end
class User < ApplicationRecord
  has_many :events_attending, class_name: "EventUser"
  has_many :events, through: :events_attending, source: :event
end

Then you can call the user's past events through current_user.events.past

CodePudding user response:

Building off of limciana's helpful answer, I modified the associations in the User.rb class as follows:

class User < ApplicationRecord
  has_many :event_user
  has_many :events_attending, through: :event_user, source: :event
  has_many :events  
end

I think the problem previously was that my user.events_attending expression would return EventUser records. But if I simply set it to return Events, through EventUser, then the past and future scopes seem to work seamlessly.

i.e. I can now do

current_user.events_attending.past

or

current_user.events_attending.future

and it works.

  • Related