我的应用不仅包含用户,还包含管理员和超级用户。由于所有三个共享相同的属性,我只想使用一个具有附加属性“角色”的表,该表可以是“user”,“admin”或“super_admin”:
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
这样的事情来获得SuperAdmins。使用default_scope似乎让我在那里:
class SuperAdmin < Admin
default_scope where(["role = ?", "super_admin"])
# ...
end
现在我也向管理员添加了default_scope:
class Admin < User
default_scope where(["role = ?", "admin"])
# ...
end
Aaaand ... SuperAdmin.all不再返回任何内容。那是为什么?
答案 0 :(得分: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应该按预期工作。
答案 1 :(得分:3)
任何像我一样对此进行挫折的人,还有另一种选择(更好的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]