index.html.erb
<%= turbo_stream_from "posts" %>
<%= turbo_frame_tag "posts" do %>
<%= render partial:'posts/post', collection: @posts, as: :post %>
<% end %>
_post.html.erb
<% if Current.user.id == post.user_id %>
<div class="d-flex justify-content-between">
<%= link_to edit_post_path(post), title:'Edit', class:"text-secondary",data: { turbo: false } do %>
<i class="fa-solid fa-pen-to-square fs-3"></i>
<% end %>
<%= button_to post, method: :delete, class:'btn btn-danger',title:'Delete' do %>
<i class="fa-solid fa-trash-can"></i>
<% end %>
</div>
<% end %>
post.rb
after_create_commit -> {
broadcast_prepend_to("posts")
}
当我在 after_create_commit 之前添加帖子时,帖子会被添加到前面,但无法获取正确的 Current.user。所以,这个
<% if Current.user.id == post.user_id %>
条件只有在刷新后才得到满足!
帮助我让它工作..!
发生这种情况的原因是因为在turbo_stream中你不能有任何对视图上下文的引用。视图上下文是您在视图内部时所处的对象,它具有您喜欢使用的所有方法(例如助手)。要解决此问题,您需要更改变量的引用,然后将其传递到列表中以及广播时。这最终看起来像
<%= render partial:'posts/post', collection: @posts, as: :post, current_user: Current.user %>
并且在回调中,您需要传入要更新的用户,因为您无法在此处访问 Current.user
broadcast_prepend_to("posts", locals: { current_user: user_to_update })
这可行,但需要您了解要更新的用户。
解决此问题的另一个选项是使用控制器端的 turbo_stream 响应,但这只会更新当前用户的页面
您需要直接使用 ActionCable 实施该解决方案。当您在客户端捕获操作时,向后端发出请求以检索当前用户,然后对用户和之前通过 ActionCable 接收到的信息执行您需要执行的操作。