2016-07-05 14 views
0

Ich versuche herauszufinden, wie man in meiner Artikelpolitik Pandit-Richtlinienbereiche verwendet.Schienen - mit Pundit Scopes in der Politik

Ich habe eine Artikelrichtlinie geschrieben, die einen Bereich verschachtelt und dann eine Auflösungsmethode enthält. Die Entschlossenheitsmethode hat Alternativen, basierend darauf, wer der current_user ist.

Mein Artikel Politik:

class ArticlePolicy < ApplicationPolicy 
    class Scope < Scope 
     attr_reader :user, :scope 

     # I now think I don't need these actions because I have changed the action in the articles controller to look for policy scope. 
     # def index? 
     #  article.state_machine.in_state?(:publish) 
     # end 

      def show? 

      article.state_machine.in_state?(:publish) || 
      user == article.user || 
      article.state_machine.in_state?(:review) && user.org_approver || 
      false 
     end 
      end 

      def create? 
       article.user.has_role?(:author) 

      end 

      def update? 
       # user && user.article.exists?(article.id) #&& user.article.created_at < 15.minutes.ago 
       user.present? && user == article.user 
       # add current state is not published or approved 
      end 

      def destroy? 
       user.present? && user == article.user 
       # user.admin? 
       # user.present? 
       # user && user.article.exists?(article.id) 
      end 



    end  

    private 
     def article 
      record 
     end 

     def resolve 
      if user == article.user 
       scope.where(user_id: user_id) 
      elsif approval_required? 
       scope.where(article.state_machine.in_state?(:review)).(user.has_role?(:org_approver)) 
      else 
       article.state_machine.in_state?(:publish)  
      end 
     end 


     def approval_required? 

      true if article.user.has_role?(:author) 
       # elsif article.user.profile.organisation.onboarding.article_approval == true 


      # if onboarding (currently in another branch) requires org approval 
     end 

     def org_approver 
      if article.user.has_role? :author 
       user.has_role? :editor 
      # if onboarding (currently in another branch) requires org approval, then the approval manager for that org 
      elsif article.user.has_role? :blogger 
       user.has_role? :editor if user.profile.organisation.id == article.user.profile.organisation.id 
      end 
     end 

end 

Das Beispiel in dem Pandit docs zeigt, wie dies für einen Index verwenden, aber wie verwende ich die Entschlossenheit Methode für eine Show-Aktion? Kann ich mehrere Auflösungsmethoden für die verschiedenen anderen Controller-Aktionen schreiben?

Pundit Scopes

Antwort

1

ich nicht mit pundit viel Erfahrung haben, aber durch den Code an Dokumentation und Code suchen I 2 Dinge sehen kann.

1 - Sie sollten keine Methoden wie show? innerhalb Ihrer Scope-Klasse verwenden.

Innerhalb Ihrer Scope-Klasse sollten Sie nur Methoden verwenden, die einen Bereich zurückgeben. Die Methoden, die Boolean zurückgeben, sollten sich auf der Richtlinienebene befinden. Aber in Ihrem Code kann ich boolesche Methoden innerhalb der Scope-Klasse verwenden.

Instances of this class respond to the method resolve, which should return some kind of result which can be iterated over. For ActiveRecord classes, this would usually be an ActiveRecord::Relation.

from the docs

2 - Da Scope sind Poros (Plain Old Ruby-Object) Sie können mehr als eine resolve Methoden haben (natürlich mit einem anderen Namen :)), weil Entschlossenheit gerade ist ein Methodenname

Mai werden Sie so etwas wie

#policy 
class ArticlePolicy < ApplicationPolicy 
    attr_reader :user, :scope 

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


    class Scope < Scope 
    def resolve 
     # some scope 
    end 

    def resolve_show 
     #scope for show action 
     # E.g scope.all 
    end 
    end 

    def show? 
    article.state_machine.in_state?(:publish) || 
     user == article.user || 
     article.state_machine.in_state?(:review) && user.org_approver || false 
    end 
end 

in Ihrem Controller

#Articles controller 
class ArticlesController < ApplicationController 
    ... 
    def show 
    authorize Article 
    ArticlePolicy::Scope.new(current_user, Article).resolve_show 
    end 
    ... 
end 

Dies sollte zuerst von ArticlePolicy::Scope#resolve_show mit ArticlePolicy#show? und den Umfang der Show-Methode genehmigen

Haftungsausschluss tun können: Ungeprüfte Code , verwenden Sie auf eigene Gefahr;)

+0

Vielen Dank so viel @ sameera207. Das hat mich dazu gebracht, die Probleme zu lösen. Für andere - die Bereiche müssen von den Aktionskontrollen getrennt werden. Die Bereiche können für die Besonderheiten des Datensatzes nuanciert werden. Die Aktionssteuerungen müssen in der Lage sein, ein wahres oder falsches Ergebnis zu liefern (und wenn zutreffend, wird der Gültigkeitsbereich dann angewendet). – Mel