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]