Module: Turbo::Broadcastable
- Extended by:
- ActiveSupport::Concern
- Defined in:
- app/models/concerns/turbo/broadcastable.rb
Overview
Turbo streams can be broadcast directly from models that include this module (this is automatically done for Active Records). This makes it convenient to execute both synchronous and asynchronous updates, and render directly from callbacks in models or from controllers or jobs that act on those models. Here’s an example:
class Clearance < ApplicationRecord
belongs_to :petitioner, class_name: "Contact"
belongs_to :examiner, class_name: "User"
after_create_commit :broadcast_later
private
def broadcast_later
broadcast_prepend_later_to examiner.identity, :clearances
end
end
This is an example from [HEY](hey.com), and the clearance is the model that drives [the screener](hey.com/features/the-screener/), which gives users the power to deny first-time senders (petitioners) access to their attention (as the examiner). When a new clearance is created upon receipt of an email from a first-time sender, that’ll trigger the call to broadcast_later, which in turn invokes broadcast_prepend_later_to
.
That method enqueues a Turbo::Streams::ActionBroadcastJob
for the prepend, which will render the partial for clearance (it knows which by calling Clearance#to_partial_path, which in this case returns clearances/_clearance.html.erb
), send that to all users that have subscribed to updates (using turbo_stream_from(examiner.identity, :clearances)
in a view) using the Turbo::StreamsChannel
under the stream name derived from [ examiner.identity, :clearances ]
, and finally prepend the result of that partial rendering to the target identified with the dom id “clearances” (which is derived by default from the plural model name of the model, but can be overwritten).
You can also choose to render html instead of a partial inside of a broadcast you do this by passing the html: option to any broadcast method that accepts the **rendering argument
class Message < ApplicationRecord
belongs_to :user
after_create_commit :update_message_count
private
def
broadcast_update_to(user, :messages, target: "message-count", html: "<p> #{user..count} </p>")
end
end
There are four basic actions you can broadcast: remove
, replace
, append
, and prepend
. As a rule, you should use the _later
versions of everything except for remove when broadcasting within a real-time path, like a controller or model, since all those updates require a rendering step, which can slow down execution. You don’t need to do this for remove, since only the dom id for the model is used.
In addition to the four basic actions, you can also use broadcast_render_later
or broadcast_render_later_to
to render a turbo stream template with multiple actions.
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#broadcast_action(action, target: broadcast_target_default, **rendering) ⇒ Object
Same as
#broadcast_action_to
, but the designated stream is automatically set to the current model. -
#broadcast_action_later(action:, target: broadcast_target_default, **rendering) ⇒ Object
Same as
#broadcast_action_later_to
, but the designated stream is automatically set to the current model. -
#broadcast_action_later_to(*streamables, action:, target: broadcast_target_default, **rendering) ⇒ Object
Same as
broadcast_action_to
but run asynchronously via aTurbo::Streams::BroadcastJob
. -
#broadcast_action_to(*streamables, action:, target: broadcast_target_default, **rendering) ⇒ Object
Broadcast a named
action
, allowing for dynamic dispatch, instead of using the concrete action methods. -
#broadcast_after_to(*streamables, target:, **rendering) ⇒ Object
Insert a rendering of this broadcastable model after the target identified by it’s dom id passed as
target
for subscribers of the stream name identified by the passedstreamables
. -
#broadcast_append(target: broadcast_target_default, **rendering) ⇒ Object
Same as
#broadcast_append_to
, but the designated stream is automatically set to the current model. -
#broadcast_append_later(target: broadcast_target_default, **rendering) ⇒ Object
Same as
#broadcast_append_later_to
, but the designated stream is automatically set to the current model. -
#broadcast_append_later_to(*streamables, target: broadcast_target_default, **rendering) ⇒ Object
Same as
broadcast_append_to
but run asynchronously via aTurbo::Streams::BroadcastJob
. -
#broadcast_append_to(*streamables, target: broadcast_target_default, **rendering) ⇒ Object
Append a rendering of this broadcastable model to the target identified by it’s dom id passed as
target
for subscribers of the stream name identified by the passedstreamables
. -
#broadcast_before_to(*streamables, target:, **rendering) ⇒ Object
Insert a rendering of this broadcastable model before the target identified by it’s dom id passed as
target
for subscribers of the stream name identified by the passedstreamables
. -
#broadcast_prepend(target: broadcast_target_default, **rendering) ⇒ Object
Same as
#broadcast_prepend_to
, but the designated stream is automatically set to the current model. -
#broadcast_prepend_later(target: broadcast_target_default, **rendering) ⇒ Object
Same as
#broadcast_prepend_later_to
, but the designated stream is automatically set to the current model. -
#broadcast_prepend_later_to(*streamables, target: broadcast_target_default, **rendering) ⇒ Object
Same as
broadcast_prepend_to
but run asynchronously via aTurbo::Streams::BroadcastJob
. -
#broadcast_prepend_to(*streamables, target: broadcast_target_default, **rendering) ⇒ Object
Prepend a rendering of this broadcastable model to the target identified by it’s dom id passed as
target
for subscribers of the stream name identified by the passedstreamables
. -
#broadcast_remove ⇒ Object
Same as
#broadcast_remove_to
, but the designated stream is automatically set to the current model. -
#broadcast_remove_to(*streamables, target: self) ⇒ Object
Remove this broadcastable model from the dom for subscribers of the stream name identified by the passed streamables.
-
#broadcast_render_later(**rendering) ⇒ Object
Render a turbo stream template asynchronously with this broadcastable model passed as the local variable using a
Turbo::Streams::BroadcastJob
. -
#broadcast_render_later_to(*streamables, **rendering) ⇒ Object
Same as
broadcast_render_later
but run with the added option of naming the stream using the passedstreamables
. -
#broadcast_replace(**rendering) ⇒ Object
Same as
#broadcast_replace_to
, but the designated stream is automatically set to the current model. -
#broadcast_replace_later(**rendering) ⇒ Object
Same as
#broadcast_replace_later_to
, but the designated stream is automatically set to the current model. -
#broadcast_replace_later_to(*streamables, **rendering) ⇒ Object
Same as
broadcast_replace_to
but run asynchronously via aTurbo::Streams::BroadcastJob
. -
#broadcast_replace_to(*streamables, **rendering) ⇒ Object
Replace this broadcastable model in the dom for subscribers of the stream name identified by the passed
streamables
. -
#broadcast_update(**rendering) ⇒ Object
Same as
#broadcast_update_to
, but the designated stream is automatically set to the current model. -
#broadcast_update_later(**rendering) ⇒ Object
Same as
#broadcast_update_later_to
, but the designated stream is automatically set to the current model. -
#broadcast_update_later_to(*streamables, **rendering) ⇒ Object
Same as
broadcast_update_to
but run asynchronously via aTurbo::Streams::BroadcastJob
. -
#broadcast_update_to(*streamables, **rendering) ⇒ Object
Update this broadcastable model in the dom for subscribers of the stream name identified by the passed
streamables
.
Instance Method Details
#broadcast_action(action, target: broadcast_target_default, **rendering) ⇒ Object
Same as #broadcast_action_to
, but the designated stream is automatically set to the current model.
223 224 225 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 223 def broadcast_action(action, target: broadcast_target_default, **rendering) broadcast_action_to self, action: action, target: target, **rendering end |
#broadcast_action_later(action:, target: broadcast_target_default, **rendering) ⇒ Object
Same as #broadcast_action_later_to
, but the designated stream is automatically set to the current model.
274 275 276 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 274 def broadcast_action_later(action:, target: broadcast_target_default, **rendering) broadcast_action_later_to self, action: action, target: target, **rendering end |
#broadcast_action_later_to(*streamables, action:, target: broadcast_target_default, **rendering) ⇒ Object
Same as broadcast_action_to
but run asynchronously via a Turbo::Streams::BroadcastJob
.
269 270 271 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 269 def broadcast_action_later_to(*streamables, action:, target: broadcast_target_default, **rendering) Turbo::StreamsChannel.broadcast_action_later_to(*streamables, action: action, target: target, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_action_to(*streamables, action:, target: broadcast_target_default, **rendering) ⇒ Object
Broadcast a named action
, allowing for dynamic dispatch, instead of using the concrete action methods. Examples:
# Sends <turbo-stream action="prepend" target="clearances"><template><div id="clearance_5">My Clearance</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_action_to examiner.identity, :clearances, action: :prepend, target: "clearances"
218 219 220 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 218 def broadcast_action_to(*streamables, action:, target: broadcast_target_default, **rendering) Turbo::StreamsChannel.broadcast_action_to(*streamables, action: action, target: target, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_after_to(*streamables, target:, **rendering) ⇒ Object
Insert a rendering of this broadcastable model after the target identified by it’s dom id passed as target
for subscribers of the stream name identified by the passed streamables
. The rendering parameters can be set by appending named arguments to the call. Examples:
# Sends <turbo-stream action="after" target="clearance_5"><template><div id="clearance_6">My Clearance</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_after_to examiner.identity, :clearances, target: "clearance_5"
# Sends <turbo-stream action="after" target="clearance_5"><template><div id="clearance_6">Other partial</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_after_to examiner.identity, :clearances, target: "clearance_5",
partial: "clearances/other_partial", locals: { a: 1 }
167 168 169 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 167 def broadcast_after_to(*streamables, target:, **rendering) Turbo::StreamsChannel.broadcast_after_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_append(target: broadcast_target_default, **rendering) ⇒ Object
Same as #broadcast_append_to
, but the designated stream is automatically set to the current model.
188 189 190 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 188 def broadcast_append(target: broadcast_target_default, **rendering) broadcast_append_to self, target: target, **rendering end |
#broadcast_append_later(target: broadcast_target_default, **rendering) ⇒ Object
Same as #broadcast_append_later_to
, but the designated stream is automatically set to the current model.
254 255 256 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 254 def broadcast_append_later(target: broadcast_target_default, **rendering) broadcast_append_later_to self, target: target, **rendering end |
#broadcast_append_later_to(*streamables, target: broadcast_target_default, **rendering) ⇒ Object
Same as broadcast_append_to
but run asynchronously via a Turbo::Streams::BroadcastJob
.
249 250 251 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 249 def broadcast_append_later_to(*streamables, target: broadcast_target_default, **rendering) Turbo::StreamsChannel.broadcast_append_later_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_append_to(*streamables, target: broadcast_target_default, **rendering) ⇒ Object
Append a rendering of this broadcastable model to the target identified by it’s dom id passed as target
for subscribers of the stream name identified by the passed streamables
. The rendering parameters can be set by appending named arguments to the call. Examples:
# Sends <turbo-stream action="append" target="clearances"><template><div id="clearance_5">My Clearance</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_append_to examiner.identity, :clearances, target: "clearances"
# Sends <turbo-stream action="append" target="clearances"><template><div id="clearance_5">Other partial</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_append_to examiner.identity, :clearances, target: "clearances",
partial: "clearances/other_partial", locals: { a: 1 }
183 184 185 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 183 def broadcast_append_to(*streamables, target: broadcast_target_default, **rendering) Turbo::StreamsChannel.broadcast_append_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_before_to(*streamables, target:, **rendering) ⇒ Object
Insert a rendering of this broadcastable model before the target identified by it’s dom id passed as target
for subscribers of the stream name identified by the passed streamables
. The rendering parameters can be set by appending named arguments to the call. Examples:
# Sends <turbo-stream action="before" target="clearance_5"><template><div id="clearance_4">My Clearance</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_before_to examiner.identity, :clearances, target: "clearance_5"
# Sends <turbo-stream action="before" target="clearance_5"><template><div id="clearance_4">Other partial</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_before_to examiner.identity, :clearances, target: "clearance_5",
partial: "clearances/other_partial", locals: { a: 1 }
151 152 153 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 151 def broadcast_before_to(*streamables, target:, **rendering) Turbo::StreamsChannel.broadcast_before_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_prepend(target: broadcast_target_default, **rendering) ⇒ Object
Same as #broadcast_prepend_to
, but the designated stream is automatically set to the current model.
209 210 211 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 209 def broadcast_prepend(target: broadcast_target_default, **rendering) broadcast_prepend_to self, target: target, **rendering end |
#broadcast_prepend_later(target: broadcast_target_default, **rendering) ⇒ Object
Same as #broadcast_prepend_later_to
, but the designated stream is automatically set to the current model.
264 265 266 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 264 def broadcast_prepend_later(target: broadcast_target_default, **rendering) broadcast_prepend_later_to self, target: target, **rendering end |
#broadcast_prepend_later_to(*streamables, target: broadcast_target_default, **rendering) ⇒ Object
Same as broadcast_prepend_to
but run asynchronously via a Turbo::Streams::BroadcastJob
.
259 260 261 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 259 def broadcast_prepend_later_to(*streamables, target: broadcast_target_default, **rendering) Turbo::StreamsChannel.broadcast_prepend_later_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_prepend_to(*streamables, target: broadcast_target_default, **rendering) ⇒ Object
Prepend a rendering of this broadcastable model to the target identified by it’s dom id passed as target
for subscribers of the stream name identified by the passed streamables
. The rendering parameters can be set by appending named arguments to the call. Examples:
# Sends <turbo-stream action="prepend" target="clearances"><template><div id="clearance_5">My Clearance</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_prepend_to examiner.identity, :clearances, target: "clearances"
# Sends <turbo-stream action="prepend" target="clearances"><template><div id="clearance_5">Other partial</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_prepend_to examiner.identity, :clearances, target: "clearances",
partial: "clearances/other_partial", locals: { a: 1 }
204 205 206 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 204 def broadcast_prepend_to(*streamables, target: broadcast_target_default, **rendering) Turbo::StreamsChannel.broadcast_prepend_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_remove ⇒ Object
Same as #broadcast_remove_to
, but the designated stream is automatically set to the current model.
97 98 99 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 97 def broadcast_remove broadcast_remove_to self end |
#broadcast_remove_to(*streamables, target: self) ⇒ Object
Remove this broadcastable model from the dom for subscribers of the stream name identified by the passed streamables. Example:
# Sends <turbo-stream action="remove" target="clearance_5"></turbo-stream> to the stream named "identity:2:clearances"
clearance.broadcast_remove_to examiner.identity, :clearances
92 93 94 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 92 def broadcast_remove_to(*streamables, target: self) Turbo::StreamsChannel.broadcast_remove_to(*streamables, target: target) end |
#broadcast_render_later(**rendering) ⇒ Object
Render a turbo stream template asynchronously with this broadcastable model passed as the local variable using a Turbo::Streams::BroadcastJob
. Example:
# Template: entries/_entry.turbo_stream.erb
<%= turbo_stream.remove entry %>
<%= turbo_stream.append "entries", entry if entry.active? %>
Sends:
<turbo-stream action="remove" target="entry_5"></turbo-stream>
<turbo-stream action="append" target="entries"><template><div id="entry_5">My Entry</div></template></turbo-stream>
…to the stream named “entry:5”
293 294 295 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 293 def broadcast_render_later(**rendering) broadcast_render_later_to self, **rendering end |
#broadcast_render_later_to(*streamables, **rendering) ⇒ Object
Same as broadcast_render_later
but run with the added option of naming the stream using the passed streamables
.
299 300 301 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 299 def broadcast_render_later_to(*streamables, **rendering) Turbo::StreamsChannel.broadcast_render_later_to(*streamables, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_replace(**rendering) ⇒ Object
Same as #broadcast_replace_to
, but the designated stream is automatically set to the current model.
116 117 118 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 116 def broadcast_replace(**rendering) broadcast_replace_to self, **rendering end |
#broadcast_replace_later(**rendering) ⇒ Object
Same as #broadcast_replace_later_to
, but the designated stream is automatically set to the current model.
234 235 236 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 234 def broadcast_replace_later(**rendering) broadcast_replace_later_to self, **rendering end |
#broadcast_replace_later_to(*streamables, **rendering) ⇒ Object
Same as broadcast_replace_to
but run asynchronously via a Turbo::Streams::BroadcastJob
.
229 230 231 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 229 def broadcast_replace_later_to(*streamables, **rendering) Turbo::StreamsChannel.broadcast_replace_later_to(*streamables, target: self, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_replace_to(*streamables, **rendering) ⇒ Object
Replace this broadcastable model in the dom for subscribers of the stream name identified by the passed streamables
. The rendering parameters can be set by appending named arguments to the call. Examples:
# Sends <turbo-stream action="replace" target="clearance_5"><template><div id="clearance_5">My Clearance</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_replace_to examiner.identity, :clearances
# Sends <turbo-stream action="replace" target="clearance_5"><template><div id="clearance_5">Other partial</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_replace_to examiner.identity, :clearances, partial: "clearances/other_partial", locals: { a: 1 }
111 112 113 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 111 def broadcast_replace_to(*streamables, **rendering) Turbo::StreamsChannel.broadcast_replace_to(*streamables, target: self, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_update(**rendering) ⇒ Object
Same as #broadcast_update_to
, but the designated stream is automatically set to the current model.
135 136 137 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 135 def broadcast_update(**rendering) broadcast_update_to self, **rendering end |
#broadcast_update_later(**rendering) ⇒ Object
Same as #broadcast_update_later_to
, but the designated stream is automatically set to the current model.
244 245 246 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 244 def broadcast_update_later(**rendering) broadcast_update_later_to self, **rendering end |
#broadcast_update_later_to(*streamables, **rendering) ⇒ Object
Same as broadcast_update_to
but run asynchronously via a Turbo::Streams::BroadcastJob
.
239 240 241 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 239 def broadcast_update_later_to(*streamables, **rendering) Turbo::StreamsChannel.broadcast_update_later_to(*streamables, target: self, **broadcast_rendering_with_defaults(rendering)) end |
#broadcast_update_to(*streamables, **rendering) ⇒ Object
Update this broadcastable model in the dom for subscribers of the stream name identified by the passed streamables
. The rendering parameters can be set by appending named arguments to the call. Examples:
# Sends <turbo-stream action="update" target="clearance_5"><template><div id="clearance_5">My Clearance</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_update_to examiner.identity, :clearances
# Sends <turbo-stream action="update" target="clearance_5"><template><div id="clearance_5">Other partial</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
clearance.broadcast_update_to examiner.identity, :clearances, partial: "clearances/other_partial", locals: { a: 1 }
130 131 132 |
# File 'app/models/concerns/turbo/broadcastable.rb', line 130 def broadcast_update_to(*streamables, **rendering) Turbo::StreamsChannel.broadcast_update_to(*streamables, target: self, **broadcast_rendering_with_defaults(rendering)) end |