6

我的应用程序不仅有用户,还有管理员和超级管理员。由于所有三个共享相同的属性,我只想使用一个带有附加属性“角色”的表,该属性可以是“用户”、“管理员”或“超级管理员”:

class User < ActiveRecord::Base
 # with nickname and password
end


class Admin < User

  def power
    puts "admin rights"
  end
end


class SuperAdmin < Admin

  def superpower
    puts "I've got the #{power}!"
  end
end

现在我想做一些事情,比如SuperAdmin.all只获得超级管理员。使用 default_scope 似乎可以让我到达那里:

class SuperAdmin < Admin
  default_scope where(["role = ?", "super_admin"])

  # ...
end

现在我也在向 Admin 添加一个 default_scope:

class Admin < User
  default_scope where(["role = ?", "admin"])

  # ...
end

Aaaand... SuperAdmin.all 不再返回任何内容。这是为什么?

4

2 回答 2

9

如果有多个 default_scope,ActiveRecord 会链接它们。所以 SuperAdmin.all 寻找具有“Admin”和“SuperAdmin”角色的用户——这永远不会发生。

为了解决这个问题,您可以覆盖继承模型的 default_scope,因此只需自己定义一个 self.default_scope :

 class SuperAdmin < Admin
    def self.default_scope
        where(["role = ?", "super_admin"])
    end
    #...
 end

SuperAdmin.all 现在应该可以按预期工作了。

于 2012-09-07T13:38:19.830 回答
8

任何像我这样偶然发现的人,还有另一种选择(更好的 imo)。

您可以简单地删除所有default_scopes定义为数组的 。

class Admin < User
  # This line will clear all the default_scopes defined in parent classes
  self.default_scopes = []
  default_scope { ... }
end

请参阅此处的源代码 https://apidock.com/rails/ActiveRecord/Base/default_scope/class。您可以看到它所做的只是将后续默认范围添加到数组中。

self.default_scopes = default_scopes + [scope]
于 2017-04-05T00:39:22.200 回答