代码之家  ›  专栏  ›  技术社区  ›  StefanS

ACL9只找到满足对象的模型对象。接受角色?(角色名称,当前用户)

  •  4
  • StefanS  · 技术社区  · 16 年前

    我是Rails的新手,这是我第一次真正使用AuthLogic+ACL9。我遵循了两个插件的默认安装步骤。

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

    假设我有一个名为产品的模型类。创建新产品对象时,我将当前用户分配为所有者:

    current_user.has_role! :owner, @product
    

    我注册了第二个用户,并确保这部分工作正常。

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

    def index
      @products = Products.all
    end
    

    我的问题是:如何在产品上调用find方法,以便仅获取当前用户为:所有者的产品? 所以我使用的ACL9接口意味着:

    @product.accepts_role?(:owner, current_user)
    

    一种可能是首先检索所有产品,然后只使用当前用户的产品创建一个新的数组。所以可能是这样:

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

    这个解决方案似乎相当浪费。那么,正确的方法是什么呢?

    谢谢大家!

    4 回复  |  直到 11 年前
        1
  •  1
  •   ernd enson    16 年前

    如何在一个查询中执行所有操作:

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

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

        2
  •  0
  •   d2kagw    16 年前

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

    我很想在role和role用户表上与products表进行一些连接,但最终采用了上述方法。

    现在工作得很好,但不能很好地扩展。

        3
  •  0
  •   morhekil    16 年前

    我不知道你为什么要加入。如果您遵循了ACL9的默认设置,那么用户与其角色之间应该有多对多的关系,角色与每个授权对象之间应该有多对一的关系。因此,如果您在模型中正确地指定了所有的关系,那么您应该能够使用简单的

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

    您可能需要在角色模型中将产品具体描述为命名范围或关联,并且您还可以通过将查找器包装到命名范围来简化整个过程。

        4
  •  0
  •   smathy    11 年前

    将这些作用域添加到 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 方法,如果您已将其设置为其他值(这是非常常见的操作),则在范围内对其进行调整。

    推荐文章