Home > OS >  How can users have a different status for each event without duplicating in Rails?
How can users have a different status for each event without duplicating in Rails?

Time:07-20

I have a rails application where I have set up a scaffold named event and users with devise (works as expected). Now I would like to add a status with which the users can confirm, reject or be unsure of coming to an event.

Each Event should have four statuses (nothing selected (default), confirmed, unsure and reject) and every user should be able to set up his/her status for each event different.

First, I thought about a new migration to the user-table with a new column status, which would be an integer. But with this configuration, a user can only have one status every time and not a different status for every event (I haven’t found a method to link the status to each event separately).

Then I thought about a new model user_status with Active Record Associations to events and users. But I can’t find a configuration which is suitable.

How can users have a different status for each event? Maybe with fixed statuses for each event, which are always the same, but includes different users for each event? How do you configure and display this correctly?

Thanks for your answers!

CodePudding user response:

You need a third table in the middle, to handle this problem. For example UserEvent
state is just an example (I've also used rejected instead of reject, because reject is also a method for selections.

class User
  has_many :user_events 
  has_many :events, through: :user_events 
end

class Event
  has_many :user_events 
  has_many :users, through: :user_events 
end

class UserEvent
  belongs_to :user
  belongs_to :event

  enum state: %i[default confirmed unsure rejected]
end

In the database migration of the user_events-table you need to add the user_id, event_id and state (integer, if state should be an enum)

Then you can do something like

  User.first.user_events.find_by(event: Event.first).confirmed?
  => true / false

  User.first.user_events.find_by(event: Event.first).confirmed!
  => true

  # it's the same as above
  User.first.user_events.find_by(event: Event.first).update(state: :confirmed)

  # list alle events from a user
  User.first.user_events.map { |ue| [ue.event.name, ue.state] }
  • Related