使用声明性授权对嵌套资源进行属性检查

时间:2012-09-17 19:43:25

标签: ruby-on-rails declarative-authorization

我正在尝试使用filter_access_to添加attribute_check: true,但我的模型Assignment嵌套在Project上,我想检查当前用户是否已分配到该项目使他/她可以更新项目中的任务(即所有任务,而不仅仅是特定任务)。

我有下一个许可:

has_permissions_on :assignment do |a|
    to :read
    if_attribute :user, is { user }
end

在我的控制器中:

filter_access_to :all, require: :manage, context: :assignment, attribute_check: true

问题是我无法访问索引页面,因为它找不到赋值的id。

我的模特是:

class User < ActiveRecord::Base
    has_many :assignments
    has_many :projects, through: :assignments
end

class Project < ActiveRecord::Base
    has_many :assignments
    has_many :users, through: :assignments
end

class Assignment < ActiveRecord::Base
    belongs_to :user, inverse_of: :assignments
    belongs_to :project, inverse_of: :assignments
end

2 个答案:

答案 0 :(得分:3)

除非您非常具体地使用filter_access_to,否则您可以使用filter_resource_accesssee docs)代替:nested_in选项。

只需使用以下(或类似)更改您的filer_access_to行:

filter_resource_access nested_in: :projects

如果确实想要继续使用filter_access_to,那么您需要创建与Project关联的Assignment实例,并将其分配给@assignment实例变量before_filter 1}}。当您使用filter_resource_access时,这就是声明性授权所做的。

答案 1 :(得分:0)

以下是为我提供诀窍的代码:

before_filter :set_assignment
    filter_access_to [:index,:create,:destroy], require: :manage, context: :assignment, attribute_check: true
....
def set_assignment
  @project ||= Project.find(params[:project_id])
  p = {project_id: @project.id}.merge(params[:assignment] || {})
  @assignment ||= (params[:id] ? Assignment.find(params[:id]) : Assignment.new(p))
end

不知道为什么filter_resource_access :nested_in => :project不起作用。它适用于index但不适用于createdestroy