Ask A Question

Notifications

You’re not receiving notifications from this thread.

Direct Messages in Realtime with ActionCable Discussion

Andrés Da Viá Andrés Da Viá

Shouldn't be better to create a model lets say conversations with both users "sender and receiver" and maybe make messages a polymorphic association between rooms and conversations?

Reply

A bit counterintuitively, that actually makes things more complex if you treat direct messages that way. By doing that you complicate the database significantly because now you can't simply join tables since you're using polymorphic assocations. Plus your direct messages no longer have a Chatroom object meaning all your messaging code on the frontend and backend need to account for the different types and treat them differently.

By treating DMs as a special Chatroom with only 2 users, you can run the exact same Javascript and server-side code without modifications. The only rules you need to set in place (like we did in the episode) are to specify that Direct Message channels are only between two users. That's the only difference between a direct message channel and a public channel making this a lot easier to maintain.

Reply

Hey Chris, thank you for this tutorial. I asked about it a few weeks ago and I got to a solution with your feedback but it was not as technically sound when I did it on my own and it didn't work as well tbh. Have you considered doing something with WebRTC for video/voice conferencing or using something like Twilio, Pusher etc, I think that would be a kickass project and could complement this one pretty well. :) Looking forward to all the new screencasts!

Reply

Absolutely. Some WebRTC stuff is on the agenda, but not for a little while. I'm really interested in checking out Twilio's WebRTC functionality. First gotta cover a handful of other topics like APIs, but that'll be coming after those things!

Reply

Hi Chris. I have a question for you. I was playing with the code and wanted to color the username depending on if you are or if you are not the speaker.

In rails 5 and actionable (this what I am seeing in your code), unless I am wrong, you have to 2 places that need to be touched in order to so the formatting on the messages. first, on the view (here this will be under your _message.html.erb partial) that will retrieve and render when you load the page. second, on the javascript channels (coffee file. in your case chatrooms.coffee).

I was able to color code the user (mine or others) depending on the speaker name on the view side but the channel seem to be quite different as it streaming to both. I simply compared User.find(message.user_id) to current_user.

On the channel side (used for updating the messages after you have reached the page), I am not sure how to introduce that test?

Reply

Hey Stan,

I would say either do client side or server side generation of colors. Server side, you could save a "color" attribute on the user that's an RGB version of their username so you only have to generate it when they sign up. You can pass that value over the websocket and use it for rendering of messages

If you went with the client side, you could have it generate the colors on all the existing messages on the page (might need to add a data attribute for the username) and then apply the colors to the existing messages on page load, and then add it to the new messages afterwards. You can just simply store those on the style="" attribute on the span around the username so that it's added directly to the record.

Either approach would work fine. The client side one is more likely to be simpler and less data intensive because it can generate colors on the fly without storing them. I would probably go with this approach personally.

Reply

Has someone seen support for file attachment using actionable?

Reply

You'll actually want to combine websockets with direct uploads (see: https://gorails.com/episode... ) in order to accomplish this. You don't want to upload files via websockets because they're not a good medium for this. Instead, you can upload files like you normally would and then you can use the response JSON from the upload to include the file in your application.

For example, Slack file uploads submit an AJAX file upload, you send over the message via ajax so you can upload the file and then once that's complete, it broadcasts it over websockets.

Reply

Here is a question. I am developing a feature where users can direct message other users directly, without the whole chatroom.
Is it possible to use actioncable the same way to have it set up this way:
A user clicks on a "chat" button on another user's profile.
It opens a little chat box in the same window (facebook chat for example)
Ability to message other users directly through that.

Thank you.

Reply

Absolutely. You can create any UI you want for this. My example is more like Slack, but you can do the same thing and use the button to initialize displaying a popup chat box instead.

Reply

Hi there. If wanted to build a 1-to-1 direct message system for my application, would you suggest I build the prototype from "Group Chat with ActionCable" series first to get started? It's hard to know how I should approach this since you are starting off this video by using code already built in a previous series. Any help is greatly appreciated. Thanks!

Reply

It would probably be helpful to watch those because they setup the foundation for this which is kind of like a chatroom restricted to just two people. Lots of different ways you can go about it, but this is just one approach that works nicely to reuse the features of group chat.

Reply

You have this on a repo?

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 81,842+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more.

    © 2024 GoRails, LLC. All rights reserved.