0

我有一个 Ruby on Rails 应用程序,我正在为其实现 ActionCable。(为了全面披露,我是 RoR 的高级初学者,并且是 ActionCable 的完整菜鸟。我正在使用这个应用程序来了解它。)我试图弄清楚我是否可以执行以下操作:

想象一下您的标准聊天室(就像在所有 ActionCable 教程中一样),其变化在于:

  1. 用户可以在发送消息后对其进行编辑,并且
  2. 房间里的一些人拥有特殊权限(您可以将他们视为管理员用户)。这些管理员用户可以在其他人发送的消息发送后对其进行编辑。

呈现页面时,我对每条消息都有一个部分,如下所示:

# View:
<%= render :partial=>"message_line", :collection=>@messages, :locals=>{:current_user=>@user}%>
# _message_line.html.erb partial
<div><%= message_line %></div>
<div>
  <% if current_user.admin or current_user.id==message_line.user.id %>
    <%= Link to edit post... %>
  <% end %>
</div>

我已成功设置 ActionCable,这样当用户输入消息时,该消息将被广播并显示在该房间内所有用户的屏幕上。但是我不知道在收到消息时如何判断接收消息的用户是否是管理员用户,因此应该显示“编辑帖子的链接”链接。调用控制器操作将消息推送给其他人的用户不是接收消息的用户,因此控制器不知道接收用户是否是管理员(特别是考虑到有多个收件人)。

作为一个具体的例子,考虑以下设置:
聊天室中有三个用户,UserA、UserB、UserC。UserA 是管理员,UserB 和 UserC 不是。

这是应该发生的事情:

  • UserA 输入一条新消息。它向所有 3 个用户广播,并且所有 3 个用户都看到它显示在他们的屏幕上。UserA 看到编辑消息的链接,UserB 和 UserC 没有。
  • UserB 输入一条新消息。它向所有 3 个用户广播,并且所有 3 个用户都看到它显示在他们的屏幕上。用户B和用户A 看到编辑消息的链接,用户C 没有。

提前感谢您的帮助!

4

1 回答 1

0

根据此答案,您的部分内容似乎在发送之前已被渲染。这意味着current_user您的部分是发送用户,而不是查看用户,就像您可能期望的那样。

我建议在这里做同样的事情。渲染两个不同的部分,然后使用查看用户的权限来确定要使用的部分。

# controller
data[:htmlAdmin] = ApplicationController.render partial: 'partial1', locals: { message: message_line, admin: true }
data[:htmlUser] = ApplicationController.render partial: 'partial2', locals: { message: message_line, admin: false }

# partial1
<div><%= message_line %></div>
<div>
  <%= Link to edit post... %>
</div>

# partial2
<div><%= message_line %></div>

# channel
received(data) {
  if current_user.is_admin?
    $("#messages_div").prepend(data[:htmlAdmin].html)
  else
    $("#messages_div").prepend(data[:htmlUser].html)
  end
}

编辑

如果你使用 Devise,你可以通过这种方式在 ActionCable 中获取 current_user:

# app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    protected

    def find_verified_user
      if current_user = env["warden"].user
        current_user
      else
        reject_unauthorized_connection
      end
    end
  end
end
于 2021-02-13T15:06:21.177 回答