导轨 4 |使用位掩码在表单中为用户分配角色 |榜样
Posted
技术标签:
【中文标题】导轨 4 |使用位掩码在表单中为用户分配角色 |榜样【英文标题】:Rails 4 | Assign Role to User in Form using Bitmask | RoleModel 【发布时间】:2014-10-27 05:41:40 【问题描述】:我陷入了以下问题 - 我怀疑有一个简单的解决方案,但我就是想不通。
我在 Rails 4 中使用Role Model Gem。
一切正常,分配的角色作为内部位掩码完美地存储在用户模型的角色掩码属性(整数)中。
现在,我希望管理员可以通过 FORM(视图)分配和删除用户的角色。我不是 Rails Ninja,所以可能有一个技巧可以做到这一点。
根据文档,我可以执行以下操作:
# role assignment
>> u.roles = [:admin] # ['admin'] works as well
=> [:admin]
# adding roles (remove via delete or re-assign)
>> u.roles << :manager
=> [:admin, :manager]
这样就明白了。
我的方法是查询表单中的所有有效角色:
# get all valid roles that have been declared
>> User.valid_roles
=> [:admin, :manager, :author]
然后将它们列为复选框。提交表单后,我分配/删除角色。
问题: 这是正确的方法吗,这是否有效,如果有效,如何?
【问题讨论】:
我通过引入 attr_accessor 并为每个角色创建一个虚拟属性暂时解决了这个问题。然后我根据角色(取消)设置复选框。保存后,我会检查哪些值已更改并相应地添加/删除角色。这似乎有点矫枉过正,但它确实有效。如果有人有更好的解决方案,请告诉我!谢谢。 【参考方案1】:既然我没有找到方法就遇到了问题 - 这是解决方案:
更多详情here.
每个用户的多个角色
我在此答案中假设您具有符号形式的角色(在下面我修改了此解决方案以使其与符号一起使用) - 因此可以使用 Pundit 以防您使用它。
# in models/user.rb
ROLES = [:admin, :manager, :general, :custom_role, :another_custome_role, :banned]
可以为用户分配多个角色并使用位掩码将其存储到单个整数列中。首先在您的 users 表中添加一个 roles_mask 整数列。
rails 生成迁移 add_roles_mask_to_users roles_mask:integer 耙分贝:迁移 接下来,您需要将以下代码添加到 User 模型中,以获取和设置用户所属的角色列表。这将执行必要的按位运算,将角色数组转换为整数字段。
# in models/user.rb
def roles=(roles)
self.roles_mask = (roles & ROLES).map |r| 2**ROLES.index(r) .inject(0, :+)
end
def roles
ROLES.reject do |r|
((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero?
end
end
这里稍作修改以使其与 Rolify & Pundit 一起使用
def roles=(roles)
self.roles_mask = (roles.map |x| x.to_sym & ROLES).map |r| 2**ROLES.index(r) .inject(0, :+)
end
如果您使用的设计没有强参数,请不要忘记将 attr_accessible :roles 添加到您的用户模型中。
如果您使用带有 strong_parameters 的设计,无论是作为 Rails 3 应用程序中的 gem,还是作为 Rails 4 中内置的,不要忘记将角色添加到控制器的允许列表中
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) |u| u.permit(:email, :password, :password_confirmation, roles: [])
end
end
请参阅设计文档中有关强参数的部分。
您可以在视图中使用复选框来设置这些角色。
<% for role in User::ROLES %>
<%= check_box_tag "user[roles][#role]", role, @user.roles.include?(role), :name => "user[roles][]"%>
<%= label_tag "user_roles_#role", role.humanize %><br />
<% end %>
<%= hidden_field_tag "user[roles][]", "" %>
最后,您可以在 Ability 类中添加一种方便的方法来检查用户的角色。
# in models/user.rb
def is?(role)
roles.include?(role.to_s)
end
# in models/ability.rb
can :manage, :all if user.is? :admin
有关限制哪些用户可以将角色分配给其他用户的方法,请参阅自定义操作。
此功能也被提取到一个名为 role_model 的小 gem(代码和操作方法)中。
如果您不喜欢此位掩码解决方案,请参阅单独的角色模型以了解处理此问题的替代方法。
【讨论】:
以上是关于导轨 4 |使用位掩码在表单中为用户分配角色 |榜样的主要内容,如果未能解决你的问题,请参考以下文章