csc*_*sch 5 inheritance activerecord default-scope ruby-on-rails-3.2
我的应用不仅有用户,还有管理员和超级管理员.由于所有三个共享相同的属性,我只想使用一个具有附加属性"角色"的表,可以是"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
Run Code Online (Sandbox Code Playgroud)
现在我想做一些事情SuperAdmin.all,只得到SuperAdmins.使用default_scope似乎让我在那里:
class SuperAdmin < Admin
default_scope where(["role = ?", "super_admin"])
# ...
end
Run Code Online (Sandbox Code Playgroud)
现在我也将一个default_scope添加到Admin:
class Admin < User
default_scope where(["role = ?", "admin"])
# ...
end
Run Code Online (Sandbox Code Playgroud)
Aaaand ... SuperAdmin.all不再返回任何内容.这是为什么?
如果有多个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
Run Code Online (Sandbox Code Playgroud)
SuperAdmin.all应该按预期工作.
任何像我一样绊倒这个的人,还有另一种选择(更好的 imo)。
您可以简单地删除所有default_scopes定义为数组的 。
class Admin < User
# This line will clear all the default_scopes defined in parent classes
self.default_scopes = []
default_scope { ... }
end
Run Code Online (Sandbox Code Playgroud)
请参阅此处的源代码 https://apidock.com/rails/ActiveRecord/Base/default_scope/class。您可以看到它所做的只是向数组添加后续默认范围。
self.default_scopes = default_scopes + [scope]
Run Code Online (Sandbox Code Playgroud)