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] }