【问题标题】:How does roles_mask work in railsRoles_mask 如何在 Rails 中工作
【发布时间】:2018-03-10 12:04:56
【问题描述】:

按照 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 是如何从整数值中识别字符串角色的?

【问题讨论】:

    标签: ruby-on-rails authorization roles


    【解决方案1】:

    啊哈!我最喜欢的逻辑!是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,它会提到:

    # 声明有效角色 -- 如果添加更多,请不要更改顺序
    # 个角色之后,始终将它们附加到最后!

    这正是它提到的季节。如果您更改订单,则持久值为1 的用户不会知道您做了什么!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-04
      • 2016-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-03
      相关资源
      最近更新 更多