简体   繁体   English

Ruby on Rails 动作电缆:根据接收用户的权限更改显示/消息?

[英]Ruby on Rails Action Cable: Change display / message based on permissions of receiving user?

I have a Ruby on Rails application for which I am implementing ActionCable.我有一个 Ruby on Rails 应用程序,我正在为其实施 ActionCable。 (For full disclosure, I'm an advanced beginner at RoR and a complete noob with ActionCable. I'm using this app to learn about it.) I'm trying to figure out if I can do something like the following: (为了全面披露,我是 RoR 的高级初学者,并且是 ActionCable 的完整菜鸟。我正在使用这个应用程序来了解它。)我试图弄清楚我是否可以执行以下操作:

Imagine your standard chat room (like in all the ActionCable tutorials), with the twist being that:想象一下您的标准聊天室(就像在所有 ActionCable 教程中一样),其变化在于:

  1. users can edit their messages after they are sent, and用户可以在发送消息后对其进行编辑,并且
  2. some of the people in the room have special permissions (you can think of them as admin users).房间里的一些人拥有特殊权限(您可以将他们视为管理员用户)。 These admin users have the ability to edit messages sent by other people after they have been sent.这些管理员用户可以在其他人发送的消息发送后对其进行编辑。

When rendering the page, I have a partial for each message that looks something like this:呈现页面时,我对每条消息都有一个部分,如下所示:

# 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>

I have successfully set up the ActionCable such that when a user enters a message that message gets broadcast and displayed on the screens of all users in that room.我已成功设置 ActionCable,这样当用户输入消息时,该消息将被广播并显示在该房间内所有用户的屏幕上。 But I can't figure out how tell, when receiving a message, if the user receiving it is an admin user and therefore should be shown the "link to edit post" link.但是我不知道在收到消息时如何判断接收消息的用户是否是管理员用户,因此应该显示“编辑帖子的链接”链接。 The user that's invoking the controller action to push the message to everyone else is not the user receiving the message, and so therefore the controller doesn't know if the receiving user is an admin (especially given that there are multiple recipients).调用 controller 操作将消息推送给其他人的用户不是接收消息的用户,因此 controller 不知道接收用户是否是管理员(特别是考虑到有多个收件人)。

As a concrete example, consider the following setup:作为一个具体示例,请考虑以下设置:
There are three users, UserA, UserB, UserC in the chat room.聊天室中共有三个用户,UserA、UserB、UserC。 UserA is an admin, UserB and UserC are not. UserA 是管理员,UserB 和 UserC 不是。

Here's what should happen:这是应该发生的事情:

  • UserA enters a new message. UserA 输入一条新消息。 It is broadcast to all 3 users and all 3 see it displayed on their screen.它向所有 3 个用户广播,并且所有 3 个用户都看到它显示在他们的屏幕上。 UserA sees the link to edit the message, UserB and UserC do not. UserA 看到编辑消息的链接,UserB 和 UserC 没有。
  • UserB enters a new message. UserB 输入一条新消息。 It is broadcast to all 3 users and all 3 see it displayed on their screen.它向所有 3 个用户广播,并且所有 3 个用户都看到它显示在他们的屏幕上。 UserB and UserA sees the link to edit the message, UserC does not.用户B和用户A 看到编辑消息的链接,用户C 没有。

Thanks in advance for any help!提前感谢您的帮助!

Based off this answer it looks like your partial is being rendered before it is sent.根据此答案,您的部分内容似乎在发送之前已被渲染。 This means current_user in your partial is the sending user, not the viewing user, like you might expect.这意味着您部分中的current_user是发送用户,而不是您可能期望的查看用户。

I'd suggest doing the same thing here.我建议在这里做同样的事情。 Have two different partials that you render and then use the viewing user's permissions to determine which to use.渲染两个不同的部分,然后使用查看用户的权限来确定要使用的部分。

# 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
}

Edit编辑

If you use Devise, you can get current_user in ActionCable this way:如果您使用 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM