acl9只找到满足object.accepts_role的模型对象?(role_name,current_user)

时间:2009-10-29 21:05:16

标签: ruby-on-rails acl9

我对rails很新,这是我第一次使用authlogic + acl9。我按照两个插件的默认安装步骤进行操作。

到目前为止,一切都很好,但我很难找到解决这个问题的优雅解决方案:

假设我有一个名为Products的模型类。创建新的Product对象时,我将current_user指定为所有者:

current_user.has_role! :owner, @product

我注册了第二个用户,并确保此部分有效。

在产品控制器中,我有一个索引方法,只需返回所有产品:

def index
  @products = Products.all
end

我的问题是:如何在产品上调用find方法,以获得current_user为:owner的那些产品? 所以我使用acl9接口意味着:

@product.accepts_role?(:owner, current_user)

一种可能性可能是首先检索所有产品,然后仅使用current_user创建一个新数组。所以也许是这样的:

@products = []
products = Products.all
products.each do |p|
  @products << p if p.accepts_role?(:owner, current_user)
end 

这个解决方案似乎很浪费。那么正确的做法是什么?

谢谢大家!

4 个答案:

答案 0 :(得分:1)

如何在一个查询中完成所有操作:

@products = Product.all.select { |p| p.accepts_role?(:owner, current_user)}

但这个想法仍然是你自己提出的

答案 1 :(得分:0)

我最近在一个正在进行的项目中得出了同样的结论。

我很想在针对products表的role和role_user表上进行一些连接,但最终还是采用了上述方法。

现在运作良好,但不能很好地扩展。

答案 2 :(得分:0)

我不确定你为什么要加入任何联盟。如果您遵循acl9的默认设置,则应该在用户和他的角色之间建立多对多关系,并在角色和每个授权对象之间建立多对一关系。因此,如果您在模型中正确指定了所有关系,则应该能够使用简单的

来检索对象

current_user.roles.find(:first, :conditions => { :name => 'owner' }).products

您可能需要在角色模型中将产品专门描述为命名范围或关联,并且您可以通过将该查找器包装到命名范围中来进一步简化整个事物。

答案 3 :(得分:0)

将这些范围添加到Product模型中:

scope :roled_by, -> ( r, u ) { where id: u.role_objects.select(:authorizable_id).where( :name => r, :authorizable_type => self ) }
scope :owned_by, -> (u) { roled_by :owner, u }

...并将其称为:Product.owned_by current_user - 您可以使用相同的模式添加任意数量的其他角色范围(或者如果您愿意,只需调用Product.roled_by :owner, current_user)。

哦,请注意我已经使用了默认的role_objects方法,如果你将其设置为其他方法(因为它很常见),然后在范围内进行调整。