roles_mask如何在rails中工作

时间:2017-09-28 16:43:06

标签: ruby-on-rails authorization roles

按照railscasts 189 Embedded Association上的教程设置我的应用程序。就像我在教程中添加

一样
t.Integer :roles_mask

到我的用户表,以及我的模型

class User < ApplicationRecord

    ROLES = %w[admin moderator author]

    def roles= (roles)
        self.roles_mask = (roles & ROLES).map { |r| 2** ROLES.index(r) }.sum
    end

    def roles
        ROLES.reject { |r| ((roles_mask || 0) & 2** ROLES.index(r)).zero? }
    end

    def role_symbols
        roles.map(& :to_sym )
    end
end

使用表单添加和删除角色都很有效。但是如何从控制台实现这一目标呢?它究竟是如何工作的,rails如何从整数值中识别字符串角色?

1 个答案:

答案 0 :(得分:1)

AHAA!我最喜欢的逻辑!这是bits的魔力。在机器语言中,所有内容都以零和一(0-1)表示。现在回到角色

ROLES = %w[admin moderator author]

对于模型中指定的每个角色,它分配一位。

admin moderator author 
1     1         1

对于用户实例,如果您授予该角色,该位将变为1其他0

u = User.new
u.roles = [:admin]
u.admin? #=> true
u.roles_mask #=> 1
admin moderator author 
1     0         0
# Read it in reverse as 0 0 1 which in binary means 1. That's why roles_mask is 1
u.roles << :author
u.roles_mask #=> 5
admin moderator author 
1     0         1
# Read it as 1 0 1 which in binary means 5. That's why roles_mask is 5

所以,它只是有点神奇,没有其他任何维护角色分配:)阅读更多关于二进制到十进制转换here

如果您看到role_model gem的README,则会提到:

  

#声明有效角色 - 如果添加更多,请不要更改订单     #roles后来,总是将它们追加到最后!

这是它提到的季节。如果您更改订单,持久值为1的用户将不知道您的操作!