我的帖子模型带有:published
属性(布尔)和带有{{1}的用户模型} attribute( string )。有三个角色:role
我不希望角色为作者的用户能够在Post模型上设置或编辑,ROLES = %w[admin publisher author]
字段。
我正在使用CanCan(和RailsAdmin gem),我的简化Ability.rb文件如下所示:
:published
任何人都有这方面的任何提示吗?
答案 0 :(得分:13)
到目前为止,这是不可能的。但根据这个:https://github.com/ryanb/cancan/issues/326此功能应该在cancan 2.0中。
更新:你可以在CanCan 2.0分支上看到这个:https://github.com/ryanb/cancan/tree/2.0在“资源属性”部分
答案 1 :(得分:3)
查看此帖子:How do I use CanCan with rails admin to check for ownership
它显示了如何根据用户角色使字段不可见。
UPDATE 我能够使用以下代码在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')并设置默认值。
希望这有助于某人。
答案 2 :(得分: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
您需要将Project
替换为@resource
。
关于这是否比railscast中描述的方法更有效或更有效,我已经开始了。出于我的目的,它保留了原始模型完整,所以我的其他代码没有受到影响 - 只是让我给一些用户更少的可编辑字段。
答案 3 :(得分: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 %>