CanCan:限制用户根据角色设置某些模型属性的能力

我有一个Post模型,其中包含:published属性( 布尔值 )和带有role属性( 字符串 )的用户模型。 有三个角色: ROLES = %w[admin publisher author]

我不希望角色为作者的用户能够设置或编辑 Post模型上的:published字段。

我正在使用CanCan(和RailsAdmin gem),我的简化Ability.rb文件如下所示:

 class Ability include CanCan::Ability def initialize(user) user ||= User.new if user.role? :admin can :manage, :all elsif user.role? :publisher can :manage, Post elsif user.role? :author # I want to prevent these guys from setting the :published attribute end end end 

有人做过这类事的任何提示吗?

到目前为止,这是不可能的。 但根据这个: https : //github.com/ryanb/cancan/issues/326这个function应该在cancan 2.0中。

更新:你可以在CanCan 2.0分支上看到这个: https : //github.com/ryanb/cancan/tree/2.0 “资源属性”部分

看看这篇文章: 如何使用带有rails admin的CanCan来检查所有权

它显示了如何根据用户角色使字段不可见。

更新我能够使用以下代码在rails admin中设置选项:

 config.model User do edit do configure :organization do visible do bindings[:view]._current_user.max_role_name != 'admin' ? false : true end end configure :organization_id, :hidden do visible do true if bindings[:view]._current_user.max_role_name != 'admin' end default_value do bindings[:view]._current_user.organization_id if bindings[:view]._current_user.max_role_name != 'admin' end end include_all_fields end end 

如果登录用户不是管理员,则此配置将隐藏组织字段。 然后它将显示organization_id字段(设置为type =’hidden’)并设置默认值。

希望这有助于某人。

在CanCan 2.0发布之前,我已经通过创建具有受限可访问性的模型的子类来解决这个问题,例如:

 class AuthorPost < Post attr_protected :published end 

然后让作者访问AuthorPosts: can :manage => AuthorPost

然后在您的控制器中,您可以在before_filter中设置所需的资源:

 before_filter :set_resource ... private def set_resource if current_user and current_user.author? @resource = AuthorPost else @resource = Post end params[:post] ||= params[:author_post] end 

最后一点需要注意的是:您将无法在该控制器中使用load_and_authorize_resource 。 你必须手动完成,详见此处: https : //github.com/ryanb/cancan/wiki/Controller-Authorization-Example

您需要将Project替换为@resource

关于这是否比railscast中描述的方法更有效或更有效,我现在不知所措。 出于我的目的,它保留了原始模型完整,所以我的其他代码没有受到影响 - 只是让我给一些用户更少的可编辑字段。

有一种方法,我在我的项目中做了类似的事情。 但CanCan并不完全是答案。 您需要做的是根据用户角色在模型动态中使attr_accessible成为动态,因此如果您是管理员,则可以更新已发布的字段。 如果没有,那么在模型保存时,不会给该字段赋予新值。

Railscasts再次拯救: http : //railscasts.com/episodes/237-dynamic-attr-accessible

在获得实现的后端部分之后,您可以通过在视图中包含发布字段并使用角色检查或根据用户显示或隐藏字段来对前端表单执行某些操作。 我实施的粗略例子……

 <% if current_user.roles.where(:name => ['Administrator','Editor']).present? %> <%= f.label :display_name %> <%= f.text_field :display_name %> <% end %>