1

I'm developing a messaging system on rails 3. My database structure is roughly as follows:

users:  
  id  
  name  

messages:  
  id  
  body

users_messages:  
  user_id  
  message_id  
  direction  
  is_read  
  created_at  

I think I have to use *has_many :through* association to be able use relationship model:

class User < ActiveRecord::Base
  has_many :user_messages
  has_many :messages, :through => :user_messages
end

class UserMessages < ActiveRecord::Base
  belongs_to :users
  belongs_to :messages
end

class Messages < ActiveRecord::Base
  has_many :user_messages
  has_many :users, :through => :user_messages
end

I can get all user's messages by calling user.messages and detect incoming/outgoing by direction. I just do not quite understand how I create a relationship that would be able do:

  message.sender  
  message.recipient
  user.messages.first.recipient ...

As well as each message requires at least 2 row in user_messages table:

  user_id_sender , message_id, outgoing ....
  user_id_recipient, message_id, incoming ....  

Maybe my database structure is wrong? Can some body suggest more effective design?

Thank you in advance.

tereško
  • 58,060
  • 25
  • 98
  • 150
S2201
  • 1,339
  • 3
  • 18
  • 35
  • 2
    I answered a very similar question here: http://stackoverflow.com/questions/5141564/model-users-message-in-rails-3/5861534#5861534 – nathanvda Jan 13 '13 at 01:49
  • I like the @nathanvda solution. You probably want to show all the received and sent messages between two users and his way is nice to do that because you will access them with one query. With your solution you probably would have to join the received and sent in an array "manually" or do some crazy join query. With his way you get it out of the box :) – Ismael Abreu Jan 13 '13 at 03:51
  • I think it miss something. How can you detect recipient(s) of some message sent by user: user.messages.first.recipient ? And how can you show conversation between two users? – S2201 Jan 13 '13 at 08:28

1 Answers1

0

db schema:

messages:
  id
  sender_id
  recipient_id
  body  

app/model/message.rb:

class Messages < ActiveRecord::Base
  has_many :users, :through => :user_messages
  belongs_to :sender, :class_name => 'User', :foreign_key => 'sender_id'
  belongs_to :recipient, :class_name => 'User', :foreign_key => 'recipient_id'
end

by doing so, you can do:

message.sender  
message.recipient
user.messages.first.recipient
Brian
  • 30,156
  • 15
  • 86
  • 87
  • Thanks for your answer. I tried this approach as well. There few problem with it. I have to add two bits to handle message visibility (delete operation) for sender and recipient. As well as I want to display a list of last messages of each user conversation. It requires big and heavy query. This pushed me to refactor the model... – S2201 Jan 13 '13 at 13:50