2017-01-18 2 views
1

J'ai la relation suivante entre mes classes utilisateur et page. Comment puis-je faire dans mon fichier Ability pour qu'un utilisateur modifie uniquement les pages qui lui appartiennent?cancancan Capacités avec has_and_belongs_to_many

class Ability 
    include CanCan::Ability 
    def initialize(user) 
     if user.is? :page_administrator 
     can :manage, Page 
     end 
    end 
end 

J'essaie ce qui suit, mais je ne peux toujours pas.

can :manage, Page, users: { user_id: user.id } 

Répondre

3

Le plus grand con avec has_and_belongs_to_many est qu'il ne permet pas de joindre des données à la table de jointure. Au lieu d'utiliser une jointure modèle:

class User < ApplicationRecord 
    has_many :user_pages 
    has_many :pages, through: :user_pages 
end 

class Page < ApplicationRecord 
    has_many :user_pages 
    has_many :users, through: :user_pages 
end 

class UserPage < ApplicationRecord 
    belongs_to :user 
    belongs_to :page 
end 

Cela fonctionne comme has_and_belongs_to_many sauf son pas sans tête - vous pouvez interroger directement UserPage. La seule chose que vous devez faire en plus de créer le modèle UserPage est de renommer la table de users_pages à user_pages (ou pages_users à page_users).

class RenameUsersPages < ActiveRecord::Migration[5.0] 
    def change 
    rename_table('users_pages', 'user_pages') 
    end 
end 

Cela est nécessaire car les rails relieront la table à la constante Users::Page autrement.

Maintenant vous pouvez facilement attacher un drapeau admin sur le tableau UserPage.

class AddPageAdministratorToUserPages < ActiveRecord::Migration[5.0] 
    change_table :users do |t| 
    t.boolean :admin, default: false 
    end 
end 

Maintenant, nous pouvons vérifier si un utilisateur est un administrateur en vérifiant si un enregistrement existe dans user_pages:

class Ability 
    include CanCan::Ability 
    def initialize(user) 
     can :manage, Page do |p| 
     p.user_pages.exists?(admin: true, user: user) 
     end 
    end 
end 
+0

Vous pouvez consulter le [joyau rolify] (https: // GitHub. com/RolifyCommunity/rolify) qui fournit un cadre pour l'autorisation basée sur les rôles dans de nombreuses classes. – max