4

我的应用程序不仅有用户,还有Admins和SuperAdmins。由于三个共享相同的属性,我想只使用一个表带有附加属性的“角色”,它们可以是“用户”,“管理员”或“超级管理员”:Rails:ActiveRecord的default_scope和类继承

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 

现在我加入了default_scope为Admin太:

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

    # ... 
end 

Aaaand ... SuperAdmin.all再没有返回。这是为什么?

回答

7

如果有多个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

任何人都会像我一样st upon这样,还有另一种选择(更好的是)。

您可以简单地删除所有定义为数组的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]