The descriptions here seem to imply that stream_for
is used only when passing in a record, but overall the documentation is rather vague. Can anyone explain the differences between stream_from
and stream_for
and why would you use one over the other?
Asked
Active
Viewed 8,731 times
23

Arslan Ali
- 17,418
- 8
- 58
- 76

Xavier
- 3,423
- 23
- 36
3 Answers
30
stream_for
is simply a wrapper method of stream_from
with ease.
When you need a stream that is related to a specific model, stream_for
automatically generates broadcasting from the model and channel for you.
Let's assume you have a chat_room
instance of ChatRoom
class,
stream_from "chat_rooms:#{chat_room.to_gid_param}"
or
stream_for chat_room # equivalent with stream_from "chat_rooms:Z2lkOi8vVGVzdEFwcC9Qb3N0LzE"
the two lines of code does the same thing.
https://github.com/rails/rails/blob/master/actioncable/lib/action_cable/channel/streams.rb

kevinhyunilkim
- 844
- 7
- 5
-
What is the point of the `to_gid_param` part ? Couldn't you just say `chat_room_#{params[:chat_room_id]}` ? – the_critic Nov 17 '16 at 17:40
-
Is it just for encoding an arbitrary string into a valid non-whitespace string ? Or is there any other idea behind it ? – the_critic Nov 17 '16 at 17:42
-
`stream_for is used when there is a particular record (or record and association) we want updates about. Under the hood, Action Cable is generating a unique string for that record or that record and its association and then calls the stream_for [sic -- probably should be 'stream_from'] method.`Source: https://www.sitepoint.com/action-cable-and-websockets-an-in-depth-tutorial/ – the_critic Nov 17 '16 at 17:47
-
1gid_param is hard to predict. It blocks an attacker who give random ids to get streams. – kuboon Aug 20 '17 at 19:45
-
@the_critic and how do you subscribe from the client side to a channel that you won't know in advance? I mean how do you subscribe to it? – tommyalvarez Nov 05 '18 at 12:23
-
You can send an id as params for connection. – Almaron Jan 19 '19 at 09:08
7
kevinhyunilkim's answer is almost ok, but prefix depends on channel_name, not model class.
class CommentsChannel < ApplicationCable::Channel
def subscribed
stream_for article
# is equivalent to
stream_from "#{self.channel_name}:{article.to_gid_param}"
# in this class this means
stream_from "comments:{article.to_gid_param}"
end
private
# any activerecord instance has 'to_gid_param'
def article
Article.find_by(id: params[:article_id])
end
end
you can also pass simple string to stream_for
which simply adds channel name.

kuboon
- 9,557
- 3
- 42
- 32
0
stream_for
takes an object as argument
class UserChannel < ApplicationCable::Channel
def subscribed
stream_for current_user
end
end
stream_from
takes a string as an argument
class ChatChannel < ApplicationCable::Channel
def subscribed
stream_from "chat_channel_#{params[:id]}"
end
end
check this article it deals with the concept very well in my opinion

Addo
- 273
- 3
- 8