简体   繁体   English

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

[英]acl9 find just model object which satisfys object.accepts_role?(role_name, current_user)

I'm pretty new to rails and it's the first time I'm actually using authlogic + acl9. 我对rails很新,这是我第一次使用authlogic + acl9。 I followed the default installation steps for both plugins. 我按照两个插件的默认安装步骤进行操作。

So far everything works great, but I have trouble to find an elegant solution for this problem: 到目前为止,一切都很好,但我很难找到一个优雅的解决方案来解决这个问题:

Let's say I have a model class called Products. 假设我有一个名为Products的模型类。 When creating a new Product object I assign the current_user as the owner: 创建新的Product对象时,我将current_user指定为所有者:

current_user.has_role! :owner, @product

I registered a second user and made sure that this part worked. 我注册了第二个用户,并确保此部分有效。

In the products controller I have an index method, simply returning all products: 在产品控制器中我有一个索引方法,只需返回所有产品:

def index
  @products = Products.all
end

My question is: How do I call the find method on Products in order to get just those products where the current_user is the :owner? 我的问题是:如何调用Products上的find方法以获得current_user为:owner的那些产品? So I using the acl9 interface that would mean: 所以我使用acl9接口意味着:

@product.accepts_role?(:owner, current_user)

One possibility probably would be to first retrieve all products and then create a new array with just the current_user ones. 一种可能性可能是首先检索所有产品,然后仅使用current_user创建一个新数组。 so maybe like this: 所以也许这样:

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

This solution seems pretty wasteful. 这个解决方案似乎很浪费。 So what's the right way to do it? 那么正确的方法是什么?

Thanks everyone! 感谢大家!

how about doing all in one query: 如何在一个查询中执行所有操作:

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

but the idea remains as proposed by yourself 但这个想法仍然是你自己提出的

I've recently came to the same conclusion in a project I was working on. 我最近在一个正在研究的项目中得出了同样的结论。

I was tempted to do some joins on the role and role_user tables against the products table, but ended up going with the above approach. 我很想针对products表对role和role_user表进行一些连接,但最终还是采用了上述方法。

Works well now, but it won't scale well. 现在运作良好,但它不会很好地扩展。

I'm not sure why you want to do any joins. 我不确定你为什么要做任何加入。 If you've followed the default setup for acl9, you should have many-to-many relationship between user and his roles, and many-to-one between roles and each authorization object. 如果您遵循acl9的默认设置,则应该在用户和他的角色之间建立多对多关系,并在角色和每个授权对象之间建立多对一关系。 So if you have all relationships properly specified in your models, you should be able to retrieve the objects with something as simple as 因此,如果您在模型中正确指定了所有关系,则应该能够使用简单的方法检索对象

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

You may need to specifically describe products as a named scope or association in the role model, and you can simplify the whole thing even more by wrapping that finder into a named scope as well. 您可能需要在角色模型中将产品专门描述为命名范围或关联,并且您可以通过将该查找器包装到命名范围中来进一步简化整个事物。

Add these scopes to your Product model: 将这些范围添加到您的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 }

...and call it like: Product.owned_by current_user - you can use that same pattern to add as many other role scopes as you like (or just call Product.roled_by :owner, current_user if you prefer). ...并将其称为: Product.owned_by current_user - 您可以使用相同的模式添加任意数量的其他角色作用域(或者如果您愿意Product.roled_by :owner, current_user只需调用Product.roled_by :owner, current_user )。

Oh, and notice that I've used the default role_objects method, if you've set this to something else (as it's very common to do) then adjust that in the scope. 哦,注意我已经使用了默认的role_objects方法,如果你把它设置为其他东西(因为它很常见),然后在范围内调整它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM