

Take advantage of Turbo Streams in event handlers
source link: https://blog.arkency.com/take-advantage-of-turbo-streams-in-event-handlers/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Take advantage of Turbo Streams in event handlersHi, weʼre arkency 👋
It’s been a time since Rails 7 came with Turbo and its Turbo Streams.
At first, I was a bit skeptical because of the idea of broadcasting view updates as a sort of Active Record callbacks.
Sorry, I’m simply not buying the idea of mixing WebSockets calls into a data model.
However, rejecting the concept of Turbo::Broadcastable
concern, I see Turbo Stream as a great tool and I’m sure there is a proper place for it in the Rails app architecture.
This is more or less what our typical architecture looks like.

Read models are loaded and presented on the UI. A user issues a command which is passed to the domain layer. This usually culminates in one or more domain events being published. These events are persisted and then handled synchronously or asynchronously by event handlers which update the read models. With the next page load, the user sees the updated read models. The circle is closed.
With Turbo Streams and just one more event handler, we can invoke asynchronous direct updates from the backend to the UI and significantly improve user experience.

Let’s see how we do it based on the ecommerce, our demo application.
<table>
<thead>
<tr>
<td>Number</td>
<td>Customer</td>
<td>State</td>
</tr>
</thead>
<tbody>
<% @orders.each do |order| %>
<%= turbo_stream_from "orders_order_#{order.uid}" %>
<tr>
<td><%= order.number %></td>
<td><%= order.customer %></td>
<td id="<%= "orders_order_#{order.uid}_state" %>"><%= order.state %></td>
</tr>
<% end %>
</tbody>
</table>
class Configuration
def call(event_store)
@event_store = event_store
# ... handlers building read models omitted
subscribe(
->(event) { broadcast_order_state_change(event.data.fetch(:order_id), 'Submitted') },
[Ordering::OrderSubmitted]
)
subscribe(
->(event) { broadcast_order_state_change(event.data.fetch(:order_id), "Paid") },
[Ordering::OrderConfirmed]
)
subscribe(
->(event) { broadcast_order_state_change(event.data.fetch(:order_id), "Cancelled") },
[Ordering::OrderCancelled]
)
end
private
def subscribe(handler, events)
@event_store.subscribe(handler, to: events)
end
def broadcast_order_state_change(order_id, new_state)
Turbo::StreamsChannel.broadcast_update_later_to(
"orders_order_#{order_id}",
target: "orders_order_#{order_id}_state",
html: new_state)
end
end
Boom! Any time we catch an OrderSubmitted
, OrderConfirmed
, or OrderCancelled
event, we invoke broadcasting an update. Every subscribed client receives a Turbo Streams message and updates the specific order state. Page reload is not required.
Recommend
-
13
Unscrupulous people may take advantage of your skills I used to go to unreasonable lengths to fix things which had broken due to other people skipping necessary steps in their projects. I always rationalized it as being the right...
-
10
本文是对 Turbo Streams 的详细说明,原文出自:https://turbo.hotwire.dev/handbook/streams。 Turbo Streams 将页面的更改发布为包在自解释的<turbo-stream>元素中的 H...
-
9
Copy link Member dhh commented
-
6
TIL — Removing DOM Event Handlers using AbortController TIL — Removing DOM Event Handlers using AbortController Published: 2022.06.18 | 1 minutes read Thanks to
-
3
本文已获得原作者(Yaroslav Shmarov)和 Bearer授权许可进行翻译。原文对 Rails Hotwire 技术栈核心 Turbo 的成员:Streams 和 Frames 进行了详细的对比。看过本文后对两者各自的区别,以及分别适用于哪...
-
7
Hotwire has been around for a while now. If you got a chance to create an app powered by it yet, you must have realized how easy it is to create apps that feel like single-page applications. In this blog, we will see the lesser-discovered part of...
-
11
Feb 28, 2023 Turbo Streams: How They Work and Differ From Turbo Frames No, you don’t need WebSockets to use Turbo Streams. You can simply use them to deliver mul...
-
8
Build event handlers and scale them across regions, all with serverless cloud services? Let’s try it. Is a serverless architecture realistic for every system? Of course not. But it...
-
6
Using Public Class Fields To Bind Event Handlers In JavaScript By Ben Nadel on April 8, 2023 Tags:
-
8
C++/WinRT event handlers that are lambdas with weak pointers to the parent class, part 1
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK