Search code examples
ruby-on-railsdatatablemodeldevisescaffold

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


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 rejected) and every user should be able to set up his/her status for each event different.

How can users have a different status for each event? How do you configure and display this correctly?

Thanks for your answers!


Solution

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