← Back to Upcase

Data Modeling for Beginners

(Aaron Reisman) #1

Hey there,

I feel like I’m getting the hang of Rails, however… when it comes to Data Modeling,

Thats when I get stumped.

Right now I am building a simple text messaging App where users can send messages via text to each other.

I would also like there to be a feature to send grouped text messages.

So, in my app currently I have a User and a TextMessage Model, but how would you go about defining a GroupedTextMessage? Would it be STI, just a simple Proxy Object on top of the TextMessage model?

How would you go about grouping the specific collection of TextMessages to mark them as a set?

just as a note about the data, I’d like to keep the TextMessage as a representation of a single text message. That way I can see how many text messages were sent in a group message, and also have more data to inspect if there are ever problems.

Also, maybe after giving an answer, explain the questions you would ask yourself in order to find a solution. So maybe in the future I can use the same process to find a solution. :wink:

(Alex Bush) #2


you’d want to create a join model to get a hold on group conversations. Something like GroupChat model which has_many users and has_many messages. Prbly a good idea implement the same thing for one-to-one chats as well. In this case you could still go with Join Table/Model but apply some STI, say you create a Chat object and it has two subclasses: 1) OneToOneChat and 2) GroupChat.

Let me know if makes any sense, I can clarify if needed.

(Aaron Reisman) #3

Hey Alex, thanks for the reply.

I currently am using this model.

it’d be appreciated if you could respond with an updated version of my spec and explain the concepts you’re talking about if you think they’re better than what I currently implemented.


(Alex Bush) #4

Ok, I have a sample Rails app for you to fork and play with here: [https://github.com/JayMarshal/Chat][1]

This is how I’d probably do it.

The idea is that you treat your text messages and users not as something separate like users and recipients or something of this sort but instead you have 2 relationships between your users and messages. (will try to explain but feel free to ask clarification questions)

1) you have your User model:

class User < ActiveRecord::Base
  has_many :conversations
  has_many :chats, :through => :conversations
  has_many :text_messages

which has:

  1. multiple conversations(a glue/join model between users and chats)
  2. many chats through this conversations(these are the things that know what users talk to each other and what messages they sent)
  3. several text_messages - those are the messages a particular user created/sent in/to one or many chats

2) then you got the Conversation model

class Conversation < ActiveRecord::Base
  belongs_to :user
  belongs_to :chat

This is a join model the sole purpose of which is to connect users to chats. That’s why it has only to ids: user_id and chat_id (when you add a user to a chat like this user.chats << chat ActiveRecord will automatically create one “glue” Conversation for you)

3) Chat model:

class Chat < ActiveRecord::Base
  has_many :conversations
  has_many :users, :through => :conversations, :uniq => true
  has_many :text_messages


That also as User has many conversations that connect it to users, plus it has many text_messages that were sent by users.

4) and at the end you got TextMessage itself that holds the text and knows what user created it and to what chat it belongs:

class TextMessage < ActiveRecord::Base
  belongs_to :chat
  belongs_to :user

This setup allows you to have flexible Chats that might have one-to-one conversations(only 2 users are in and can send messages to the chat) or many-to-many conversations so that several users will receive a message sent to a Chat since they all associated to this chat.

That’s of the top of my head… there are many things that could be improved and abstracted out but this should get you going :slight_smile:

As I mentioned above feel free to fork and play around with this sample(I left a couple of helpful creation snippets in comments the code) and feel free to ask questions.


Alex Bush
[1]: https://github.com/JayMarshal/Chat