Search code examples
ruby-on-railsrubychat

Chat belongs_to two instances of User, and User has_many :chats (ruby on rails )


I am building a sort of "non instant messaging system". My system consists of many Users, Chats, and Messages.

  • Users can have many Chats
  • Chats can only belong to two different Users
  • Messages belong to one User and one Chat

The way I designed it is:

rails g model Chat user1:references user2:references
rails g model Message user:references chat:references

And then in my models/chat.rb i do:

# models/chat.rb
class Chat < ApplicationRecord
  belongs_to :user1, :class_name => 'User'
  belongs_to :user2, :class_name => 'User'
end

My models/message.rb model

# models/message.rb
belongs_to :user
belongs_to :chat

And my models/user.rb model

# models/user.rb
has_many :chats
has_many :messages, through: :chats

All of this modeling makes sense to me, but i just cant get it to work. I need to be able to do something like User.find(1).chats and have it return all the user's chats. Also Chat.find(1).users would be nice. User.find(1).messages is not that much trouble since it's pretty standard relationship, but what about the others? what am i missing? I have read forum through forum but i can't seem to get any solution to work on my specific case.


Solution

  • I would suggest these changes (with assistance from @TonyArra):

    • Chats have_many messages
    • Message belongs_to a chat
    • Chats have_and_belongs_to_many (or belongs_to) users
    • Users have_and_belongs_to_many (or have_many) chats

    This would be the conventional way to model this, and I think it would support your use cases.

    I mentioned YAGNI in the comments because the OP mentioned chats only having two users. YAGNI (you aren't going to need it, so don't built it now) is a great principle. However, many chat programs support more than two users, and sometimes just one user. You could argue that building the data model with that consideration in mind is pragmatic.

    Great further reading on that subject: Preemptive Pluralization is (Probably) Not Evil