Building a Messaging System
After trying to deploy to heroku with an in-app messaging system with the mailboxer gem, the messaging system seemed to be broken. After trying to fixing it for 4 hours, with a lack of documentation on it on the internet, I decided to build my own messaging app from scratch.
This messaging system was built for my project, CampusBazaar, which allows users to message sellers about items to ask questions or to pick places to meet up on campus. Just thinking about how to organize the app was the most difficult part of the app. Knowing how the messaging app is associated with other parts of the app is important.
For my purpose, I wanted a messaging system that knows about the item that the sender is inquiring about. Any time someone inquires about an item, a new conversation is started between the two users. If the user inquires about another item from the same user, there will be a separate conversation, because it solely based on the item.
Basically, this is what should happen You will click on Contact seller button on the item show page
Then, a new conversation will be started between you two. This means the message form will be nested inside the conversation form
Lastly, this will be the messaging app containing all your conversations, and you can see all the messages that belong to that particular conversation.
To start, we should make a migration for conversations. Essentially, there will be a conversation between two users, and it is connected to an item. This is basically a join table.
1 2 3 4 5 6 7 8 9 10 |
|
Here, we have the messages migration. There will be a sender_id and recipient_id and not a user1_id and a user2_id like in the conversation migration because it matters who is the sender or not, whereas in the conversation migration, it is just two people talking to each other, regardless of who sent the message first, or who is the sender or recipient. Each messsage will belong to a conversation, hence the conversation_id.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Now for the associations. This is the conversation model. It will belong to a item, the users that are talking to each other, and has many messages. It belongs to a user with a foreign key of class name ‘User’ so that we can do ask the console about the user of that conversation when doing Conversation.user1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
This isthe messsage associations. It will belong to a conversation, also belong to a recipient and sender, associating that with the User class like in the Conversation model with foreign keys. The message will also belong to a sender. There will be many people inquiring about an item, but there will only be one buyer, who is actually going to buy the item.
1 2 3 4 5 6 |
|
Remember that if you have a belongs_to association, the counterpart will have a has_many associtation. A user will have many items and conversations as user1 or user2.
1 2 3 4 5 6 |
|
Finally, the item will have many conversations, because the conversation also belongs to an item. There will be many inquiries from potential buyers but there will just be one buyer.
1 2 3 4 5 6 7 8 9 |
|
Let’s not forget about our routes. There will be messages nested under routes, but only the GET request of index and POST of create will be needed because we will show all the messages for that particular conversation, and we need to create new messages. There will be no need of other routes such as the Show method because we will not be showing each individual message.
1 2 3 |
|
Now, understanding that we will click Contact Seller from the items page, it will do a GET request to go to the new_conversation_path to see the form to create a new conversation. We will nest the message form inside the conversation form because upon creation of a conversation, there should be a message.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
This is the form. I added hidden fields to pass into private params in th controller. Once the form is submitted, it will send a POST request to the server and do its thing at the def create in the Conversation Controller. The params will be set in the new instance Conversation and saved, and a new message will also be created with all the passed in information.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Once that conversation is created, it will redirect to the def index, to see all their conversations they ever had. If they clicked on a conversation, it will basically send a GET request to the Messages Controller to give back the index page of the messages pertaining to that conversation, given that the id of the conversation is passed in.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Where it’s actually going is /conversations/:id/messages, so params will have the id of the conversation. Javascript was used to render the partials so that when you click on the conversation, it will allow ajax to render the messages, without the page ever refreshing.