Reputation: 4169
I'm curious how this works... I have several has_many relationships between the same two models. This is for a calendaring app, so a User can be invited to an Event, a User can attend an Event, and an Event belongs to a User for purposes of seeing who created the event.
user.rb
class User < ActiveRecord::Base
has_many :invites, dependent: :destroy
has_many :events, through: :invites
has_many :events
has_many :attendances, -> { where cancel: false },
dependent: :destroy
has_many :events, -> { where "attendances.cancel" => false },
through: :attendances
event.rb
class Event < ActiveRecord::Base
has_many :invites, dependent: :destroy
has_many :users, through: :invites
belongs_to :user
has_many :attendances, -> { where cancel: false },
dependent: :destroy
has_many :users, -> { where "attendances.cancel" => false },
through: :attendances
I also have the corresponding join tables, controlled in their respective models, attendance.rb
, and invite.rb
.
So... this works as expected. A User has Events when they're attending the Event. I did some tweaking, and realized it was the last thing in the list that was checked. So, if I move the invites to the bottom, then that's what's checked when I do something like User.find(1).events
.
Is there a better way to go about this? I feel like this is just asking for trouble, no?
Upvotes: 4
Views: 2200
Reputation: 13344
When I've done this before, I've just changed the name of the relationship to something more unique, then told the has_many
what class to look at via class_name
. You'll likely have to add the foreign_key
parameter on these changed relationships as well, so the SQL knows which key to match against.
Here's the basic idea:
user.rb
class User < ActiveRecord::Base
has_many :invites, dependent: :destroy
has_many :invited_events, through: :invites, source: "Event"
has_many :events # these are events "owned" by the user
has_many :attendances, -> { where cancel: false }, dependent: :destroy
has_many :attended_events, -> { where "attendances.cancel" => false }, through: :attendances, source: "Event"
end
event.rb
class Event < ActiveRecord::Base
has_many :invites, dependent: :destroy
has_many :invitees, through: :invites, source: "User"
belongs_to :user # this is the owner of the event
has_many :attendances, -> { where cancel: false }, dependent: :destroy
has_many :attendees, -> { where "attendances.cancel" => false }, through: :attendances, source: "User"
end
Upvotes: 2