I want to stream model updates using Hotwire in Rails. In the documentation they mention creating a stream using a model but I want to create a dynamic stream per user so that changes to models done by a user are only streamed to that user.
I have a VideoCall model which has and belongs to many users via a joining table so the model looks like this and I have a broadcast as such
class VideoCall < ApplicationRecord
has_and_belongs_to_many :users
broadcasts_to ->(video_call) {
video_call.users.map{|u| "video_calls:user_#{u.id}"}
}, inserts_by: :prepend
# more code here
end
On the ERB template where I want to get the updates to the model I have added
<%= turbo_stream_from "video_calls:user_#{current_user.id}" %>
This works if I have one user in a users_video_calls table. But as soon as there are multiple users in a video_call it does not work and I want to broadcast to the stream of all of those users.
Is the approach I am taking correct and how can I achieve broadcasting to multiple users streams dynamically.
So I solved this the following way. Looking at the source code I realized that it makes sense to override the three callbacks that get called on create, update and destroy. So I removed this code
broadcasts_to ->(video_call) {
video_call.users.map{|u| "video_calls:user_#{u.id}"}
}, inserts_by: :prepend
and replaced it with this
after_create_commit -> {
self.users.each do |u|
broadcast_action_later_to "video_calls:users_#{u.id}", action: :prepend, target: broadcast_target_default
end
}
after_update_commit -> {
self.users.each do |u|
broadcast_replace_later_to "video_calls:users_#{u.id}"
end
}
after_destroy_commit -> {
self.users.each do |u|
broadcast_remove_to "video_calls:users_#{u.id}", action: :prepend, target: broadcast_target_default
end
}
In the code above now I can loop through each associated model which in my case is many users per video call and broadcast to the channel name that contains user id. So all the users subscribed to the video call will only get the update and not everyone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With