英文:
Multiple Partial Updates in Rails using Turbo Stream
问题
我有两个模型,一个是客户,另一个是投诉,一个客户可能有多个投诉。如果要将投诉添加到客户中,如何使用 Turbo Stream 来更新投诉的索引和客户的展示视图,同时使用两个不同的局部视图,确保只列出特定客户的投诉在客户展示视图中?
以下是我的一些代码:
客户模型:
class Customer < ApplicationRecord
validates_presence_of :names
belongs_to :company
has_many :complaints
broadcasts_to ->(customer) { [customer.company, "customers"] }, inserts_by: :prepend
end
投诉模型:
class Complaint < ApplicationRecord
belongs_to :company
belongs_to :customer
broadcasts_to ->(complaint) { [complaint.company, "complaints"] }, inserts_by: :prepend
end
投诉索引页面(正常流式显示):
<%= turbo_stream_from @company, "complaints" %>
<h1>Complaints</h1>
<%= link_to new_complaint_path, class: "btn", data: { turbo_frame: "remote_modal" } do %>
New
<% end %>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">Customer</th>
<th scope="col">Date</th>
<th scope="col">Note</th>
<th colspan="2"></th>
</tr>
</thead>
<tbody id="complaints">
<%= render @complaints %>
</tbody>
</table>
</div>
客户展示视图(不流式显示):
<%= turbo_stream_from @customer %>
<%= turbo_stream_from @customer, "complaints" %>
<%= turbo_frame_tag "customer" do %>
<%= @customer.names %>
<% end %>
<%= link_to edit_employee_path(@customer), class: "btn", data: { turbo_frame: "remote_modal" } do %>
Edit
<% end %>
<h4>Complaints</h4>
<%= link_to new_complaint_path, class: "btn", data: { turbo_frame: "remote_modal" } do %>
Add
<% end %>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Note</th>
<th colspan="2"></th>
</tr>
</thead>
<tbody id="complaints">
<%= render @complaints %>
</tbody>
</table>
</div>
英文:
I have two models, one for customer and one for complaints, one customer also has many complaints. If a complaint is added to the customer, how can you use Turbo Stream to update both the index of complaints and the show view of the customer using two different partials while ensuring only the specific customer's complaints are listed in the customer show view?
Here is some of my code:
Customer model:
class Customer < ApplicationRecord
validates_presence_of :names
belongs_to :company
has_many :complaints
broadcasts_to ->(customer) { [customer.company, "customers"] }, inserts_by: :prepend
end
Complaint model:
class Complaint < ApplicationRecord
belongs_to :company
belongs_to :customer
broadcasts_to ->(complaint) { [transgression.company, "complaints"] }, inserts_by: :prepend
end
Complaints index.html.erb (streaming fine):
<%= turbo_stream_from @company, "complaints" %>
<h1>Complaints</h1>
<%= link_to new_complaint_path, class: "btn", data: { turbo_frame: "remote_modal" } do %>
New
<% end %>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">Customer</th>
<th scope="col">Date</th>
<th scope="col">Note</th>
<th colspan="2"></th>
</tr>
</thead>
<tbody id="complaints">
<%= render @complaints %>
</tbody>
</table>
Customer show.html.erb view (not streaming...):
<%= turbo_stream_from @customer %>
<%= turbo_stream_from @customer, "complaints" %>
<%= turbo_frame_tag "customer" do %>
<%= @customer.names %>
<% end %>
<%= link_to edit_employee_path(@customer), :class => "btn", data: { turbo_frame: "remote_modal" } do %>
Edit
<% end %>
<h4>Complaints</h4>
<%= link_to new_complaint_path, class: "btn", data: { turbo_frame: "remote_modal" } do %>
Add
<% end %>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Note</th>
<th colspan="2"></th>
</tr>
</thead>
<tbody id="complaints">
<%= render @complaints %>
</tbody>
</table>
</div>
答案1
得分: 1
在客户展示页面上,您正在订阅@customer, "complaints"
,但您没有向其广播任何内容,因此没有更新。
# app/models/complaint.rb
class Complaint < ApplicationRecord
belongs_to :company
belongs_to :customer
# 注意:这将发送 turbo 流到`[company, "complaints"]`
# 您必须订阅该通道以接收更新。
# 默认值:
# 部分: "complaints/complaint"
# 目标: "complaints"
broadcasts_to ->(complaint) { [complaint.company, "complaints"] }, inserts_by: :prepend
# 注意:要在客户展示页面上接收更新,您必须发送更新到[customer, "complaints"]
broadcasts_to ->(complaint) { [complaint.customer, "complaints"] },
inserts_by: :prepend,
partial: "customers/complaint" # <= 如果您想使用不同的部分
end
# app/views/customers/show.html.erb
# 确保订阅您正在广播的通道
<%= turbo_stream_from @customer, "complaints" %>
# 对于传入的 turbo 流,您必须有一个 `id` 目标
<div id="complaints">
# 渲染不同的部分
<%= render partial: "customers/complaint", collection: @complaints %>
</div>
我不确定您在控制器中有什么问题,您无需为广播执行任何操作:
# app/controllers/customers_controller.rb
# GET /customers/1
def show
# 注意:仅在初始请求上显示特定客户的投诉
# 广播已经限制为`@customer`
@complaints = @customer.complaints
end
英文:
On customer show page you're subscribing to @customer, "complaints"
but you're not broadcasting anything to it, so there are no updates.
# app/models/complaint.rb
class Complaint < ApplicationRecord
belongs_to :company
belongs_to :customer
# NOTE: this will send turbo streams to `[company, "complaints"]`
# you have to be subscribed to that channel to receive updates.
# Defaults:
# partial: "complaints/complaint"
# target: "complaints"
broadcasts_to ->(complaint) { [complaint.company, "complaints"] }, inserts_by: :prepend
# NOTE: to receive updates on the customer show page you have send
# updates to [customer, "complaints"]
broadcasts_to ->(complaint) { [complaint.customer, "complaints"] },
inserts_by: :prepend,
partial: "customers/complaint" # <= if you want to use a different partial
end
# app/views/customers/show.html.erb
# make sure to subscribe to a channel that you're broadcasting to
<%= turbo_stream_from @customer, "complaints" %>
# you have to have an `id` target for the incoming `turbo_stream`
<div id="complaints">
# render a different partial
<%= render partial: "customers/complaint", collection: @complaints %>
</div>
I'm not sure what issues you have in the controllers, you don't need to do anything for broadcasts to work:
# app/controllers/customers_controller.rb
# GET /customers/1
def show
# NOTE: only show specific customer complaints on initial request
# broadcasts are already limited to `@customer`
@complaints = @customer.complaints
end
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论