按照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如何从整数值中识别字符串角色?
答案 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
的用户将不知道您的操作!