2017-04-05 178 views
0

使用cancancan的最基本的實現,覺得我瘋了。Cancancan roles_mask沒有映射

下面是在我的用戶模型

ROLES = %i[admin regular reporter] 

    # Roles logic to covert string above to/from integers 
    def roles=(roles) 
    roles = [*roles].map { |r| r.to_sym } 
    self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+) 
    end 

    def roles 
    ROLES.reject do |r| 
     ((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero? 
    end 
    end 

    def has_role?(role) 
    roles.include?(role) 
    end 

1個用戶是顯示角色:管理員

2用戶顯示角色:定期

但3用戶顯示角色[:管理員,:普通]

想不出來救我一命

回答

1

如果我正確理解您的問題,則[:admin, :regular]的3是正確的roles_mask

如果您正試圖將User設置爲reporter,它不會是3,但實際上4

這是因爲roles=方法,最基本的用法,你ROLES數組轉換爲:

ROLES_MAP = [1, 2, 4]

(...並因此允許多個角色通過添加在一起的數字被簡單地組合)

但是,如果你想設置一個用戶對象作爲一個記者,你應該使用:

@user.roles = "reporter"

,並最好不要直接設置roles_mask,像這樣:

@user.roles_mask = 4

+0

謝謝對於迴應,我最終通過使用您建議設置爲符號的方法,而不是roles_mask來解決這個問題。我很好奇爲什麼它將數組轉換爲1,2,4?我假設另外一個角色是8的roles_mask?任何理由爲什麼這是典型的解決方案? –

+0

是的,對於您正在使用的特定代碼,它允許您爲用戶提供多個角色,這些角色都存儲在一個單一的數字值中,我猜想將其存儲爲數據庫表中的一個字段。 –

+0

(如果您只希望每個用戶有一個角色,那麼您可以刪除所有代碼,只需要一個普通的舊索引數組。 –