2016-04-24 2 views
0

Je souhaite que différents types de wikis apparaissent dans l'index, en fonction du rôle de l'utilisateur. La politique pour les utilisateurs admin et standard/guest fonctionne comme il se doit, mais quand il s'agit d'utilisateurs haut de gamme et de collaborations, cela devient un peu compliqué. Dans mon application, j'ai la possibilité d'ajouter des collaborateurs au privé Wikis. Ainsi, un utilisateur Premium devrait pouvoir voir Mes wikis privés, wikis publics et wikis privés, mais les wikis privés où un collaborateur ne se présente pas. Cela pourrait-il concerner ma politique ou mes associations de modèles? S'il vous plaît, aidez-moiStratégie Pundit: les wikis ne s'affichent pas pour les collaborateurs

wiki # Index

def index 
    @wikis = Kaminari.paginate_array(policy_scope(Wiki)).page(params[:page]).per(10) 
    end 

modèle utilisateur

class User < ActiveRecord::Base 
    has_many :wikis 
    has_many :collaborators 
    belongs_to :collaborators 
.... 

modèle Wiki

class Wiki < ActiveRecord::Base 
     belongs_to :user 
     has_many :collaborators 
     has_many :users, through: :collaborators 
.... 

modèle collaborateur

class Collaborator < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :wiki 
end 

Wiki_policy

class Scope 
    attr_reader :user, :scope 

    def initialize(user, scope) 
     @user = user 
     @scope = scope 
    end 

    def resolve 
     wikis = [] 
     if user.role == 'admin' 
     wikis = scope.all # if the user is an admin, show them all the wikis 
     elsif user.role == 'premium' 
     all_wikis = scope.all 
     all_wikis.each do |wiki| 
      if wiki.private == false || wiki.owner == user || wiki.collaborators.include?(user) 
      wikis << wiki # if the user is premium, only show them public wikis, or that private wikis they created, or private wikis they are a collaborator on 
      end 
     end 
     else # this is the lowly standard user 
     all_wikis = scope.all 
     wikis = [] 
     all_wikis.each do |wiki| 
      if wiki.private == false || wiki.collaborators.include?(user) 
      wikis << wiki # only show standard users public wikis and private wikis they are a collaborator on 
      end 
     end 
     end 
     wikis # return the wikis array we've built up 
    end 
    end 

quand je vais dans la console

last = Wiki.last 
last.collaborators 

je reçois ceci:

=> #<ActiveRecord::Associations::CollectionProxy [#<Collaborator id: 7, user_id: 8, wiki_id: 104, created_at: "2016-04-24 08:07:20", updated_at: "2016-04-24 08:07:20">]> 
+0

Essayez de tester le code manuellement dans la console. Je suppose que vous n'avez pas affecté le wiki au collaborateur que vous utilisez, car il fonctionne lorsque vous êtes connecté en tant qu'utilisateur standard. Le code ne semble pas devoir échouer – joewoodward

+0

Je l'ai testé sur la console que j'ai utilisée: 'last = Wiki.last, last.collaborators' et j'ai '# ]> ' –

Répondre

1

Ah, je vois la question. Votre table de jointure est mal formée, probablement parce que vous utilisez à la fois belongs_to et has_many pour la même classe, ce qui vous a rendu confus. à savoir belongs_to: utilisateur et has_many: les utilisateurs

Vous devez profiter de la class_name dans la définition par question

-à-dire

Wiki 
    # the owner 
    belongs_to :user 

    # the collaborators join table 
    has_many :wiki_collaborators 

    # this is the object you will call from wiki.collaborators 
    has_many :collaborators, through: :wiki_collaborators, class_name: 'User' 
end 

User 
    # the wikis owned by this user 
    has_many :wikis 

    # the join table 
    has_many :wiki_collaborators 

    # this is the object you can call from user.wiki_collaborations or something else that maybe fits better 
    has_many :wiki_collaborations, through: :wiki_collaborators, class_name: 'Wiki' 
end 

WikiCollaborator 
    belongs_to :user 
    belongs_to :wiki 
end 

Vous est que lorsque vous appelez wiki.collaborator vous êtes réellement renvoyer le modèle de jointure pas le modèle d'utilisateur.

Vous pouvez réellement appeler wiki.users (remarquez pluriel) pour obtenir les collaborateurs du wiki dans le code que vous avez actuellement. Vous devez toujours corriger la ligne User belongs_to: collaborateurs. Je pense que laisser tomber la jointure de table et la régénération Collaborator comme WikiCollaborator serait plus logique et la mise en œuvre est comme je l'ai décrit

Hope this helps