用你的角色包装角色 users/_form.html.erb 文件:
users/_form.html.erb
简单的形式:
<% if can? :manage, User %> <%= f.association :roles, as: :check_boxes %> <% end %>
没有简单的形式:
<% if can? :manage, User %> <div class="control-group"> <%= f.label :roles, class: "control-label" %> <div class="controls"> <% Role.all.each do |role| %> <%= check_box_tag "user[role_ids][]", role.id, @user.role_ids.include?(role.id) %> <%= role.name %><br /> <% end %> </div> </div> <% end %>
我最终使用了before_filter,如下所示:
before_filter :prevent_unauthorized_role_setting, :only => [ :create, :update ] def prevent_unauthorized_role_setting if cannot? :manage_roles, current_user params[:user].delete_if { |k, v| k.to_sym == :role_ids } end end
同时遵循Zaid在ability.rb中的建议:
cannot :manage_roles, :users if user.has_role? :admin can :manage_roles, :users end
此外,我放弃了Rolify并自己管理角色。
我不确定我是否理解你希望主持人做什么,但这里是我使用的基本配置。我尽可能地适应你的情景。如果版主不需要个人权限,则删除内部子句。
class Ability include CanCan::Ability def initialize(user) # Create guest user aka. anonymous (not logged-in) when user is nil. user ||= User.new if user.has_role? :admin can :manage, :all elsif user.has_role? :moderator can :manage, User, user_id: user.id can :create, User can :read, :all else # Guest user aka. anonymous can :read, :all end end end
首先,你可能想要清理你的能力,因为目前似乎有些困惑。为了清楚起见,忽略其他所有内容,为密码修改指定自定义操作可能是个好主意。例如:
# ability.rb def initialize(user) ... cannot :manage_roles, :user if user.has_role? :admin can :manage_roles, :user else end
(你究竟想用其他规则来实现什么?目前如果看起来你只是让主持人阅读,编辑和删除自己,这是你想要的吗?)
您可能希望为任何无法对其执行任何操作的人隐藏或禁用表单的角色部分:
#_form.html.erb <%= simple_form_for @user do |f| %> <%= f.association :roles, as: :check_boxes if can? :manage_roles, @user %> <%= f.button :submit %> <% end %>
(注意 can? 只需要两个参数,即动作和对象/类。)
can?
如果您想要更加安全,还可以在控制器中使用以下检查:
# users_controller.rb def update @user = User.find(params[:id]) user_params = params[:user] if cannot? :manage_roles, @user user_params.delete_if { |k, v| k.to_sym == :role_ids } end if @user.update_without_password(user_params) redirect_to @user else render :action => "edit" end end
(你需要仔细检查从params哈希中删除的正确密钥是什么,我假设它是 :role_ids 基于你的 attr_accessible ,但我真的不太了解simple_form。)
:role_ids
attr_accessible