Question

So I'm trying to create a simple events web application where class User can both create class Event and participate in them. In the case class User creates a class Event, I want that event to belong_to the user. But in case that same User signs up to participate in another event, I want the user to belong_to the event, and that event to has_many Users. I don't know how this would actually be written in the models though.

In one case class User is a participant belonging to the event, and in the other they are the host and the event belongs_to them. I wan't to keep this dry and not create separate classes of users(host and participant in this case) if I don't have too. A mere joint table doesn't seem to account for this conditional association. Any advice on the best way to do this?

class User ???

class Event ????

Thanks!

Was it helpful?

Solution

You'll need to make 2 associations - one to link to created Events, and one to link to subscribed Events:

create_table :event_subscriptions do |t|
  t.references :subscribed_user
  t.references :subscribed_event
end

create_table :events do |t|
  t.references :user
  # other fields
end

class User < ActiveRecord::Base
  has_many :events               # created Events
  has_many :event_subscriptions, :foreign_key => :subscribed_user_id
  has_many :subscribed_events, :through => :event_subscriptions  # subscribed Events
end

class EventSubscription < ActiveRecord::Base
  belongs_to :subscribed_user, :class_name => 'User'
  belongs_to :subscribed_event, :class_name => 'Event'
end

class Event < ActiveRecord::Base
  belongs_to :user               # the creating User
  has_many :event_subscriptions, :foreign_key => :subscribed_event_id
  has_many :subscribed_users, :through => :event_subscriptions   # subscribed Users
end

OTHER TIPS

I would recommend you use the has_and_belongs_to_many association (documentation here). Based on what you're trying to accomplish I don't think a joint table is avoidable. Granted, that shouldn't discourage you!

I would add a "role" column of type string to the Users table (i.e. Host or Participant) and use the has_and_belongs_to_many association. Note, you will need to create a joint table users_events that contains :user_id and :event_id columns.

Then, you can have a User that has the role of, let's say "host", create an Event and invite other users of roles "participant".

Of course, this is just my suggestion. There are several ways you can go about this.

Be aware that if an event has_many :users then the user table must have a event_id column, and a user can only belong to one event at a time. I suspect you want a many to many relationship between users and events. If that is the case you would use has_and_belongs_to_many :users association documented here

That said, yes, you can have multiple relations on the same classes.

class Event < ActiveRecord::Base
  has_many :users
  belongs_to :host, :class_name => 'User'
end

The events table would have a column host_id, but event.host would still return a User.

I would handle that with a has_many and belong_to between User and Event. User has_many Events and Event belongs_to User.

The rest would be your logic. Do you want your has_many relationship to be your event owners, or your participants. I'll assume the has_many relates to Event owners.

From there create a column called participants in your Event table. In the Event or User model you can then create a before_save method that inserts the user_id of your participant.

You could then create a scope in either model that returns a list of all participants of the Event.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top