2011-05-07 63 views
18

某些型号的属性能力,我有一个邮政模型与:published属性(布尔)和用户模型与role属性()。有三种角色:ROLES = %w[admin publisher author]惨惨:限制用户对设置基于角色

我不想让用户的作用是作者应能设置,或编辑,在:published场对早报模型。

我使用的康康舞(和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 

任何人有什么秘诀做这样的事情?

回答

13

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

更新:你可以看到这对惨惨2.0分支的位置:在部分https://github.com/ryanb/cancan/tree/2.0“资源属性”

+0

好的,谢谢你,我会关注CanCan v2.0。谢谢 – stephenmurdoch 2011-05-07 14:34:11

+0

我知道这并不完美,但我认为你仍然可以使用'can not << your attribute >>,:klass bee',因为它们在等待2.0时仍然是ruby中的方法。 – 2012-12-22 06:51:06

0

有一种方法,我做了这样的事情在我的项目。但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 %> 
+0

谢谢,我喜欢这个 - 现在要去看那个railscast - 谢谢:) – stephenmurdoch 2011-05-08 13:46:14

3

退房这个帖子:How do I use CanCan with rails admin to check for ownership

它显示了如何使场不可见基于掀起了用户的角​​色。

UPDATE 我能够设置选项中轨与此代码管理:

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')并设置默认值。

希望这可以帮助别人。

+0

约翰古德曼? – 2013-05-08 21:32:21

3

直到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

您需要将替换为@resource

我很想知道这是否比railscast中描述的方法更有效或更低效。出于我的目的,它完全保留了原来的模型,所以我的其他代码不受影响 - 只允许我为一些用户提供更少的可编辑字段。