2016-07-05 2 views
0

Я пытаюсь выяснить, как использовать области политики pundit в моей политике статьи.Rails - с областями Pundit в политике

Я написал политику статьи, в которой находится область действия, а затем в ней есть метод разрешения. Метод разрешения имеет альтернативы на основе того, кем является current_user.

Моя статья политики:

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 

Пример в Пандит документации показывает, как использовать это для индекса, но как я использую метод разрешить для шоу действий? Могу ли я написать несколько методов решения для других действий контроллера?

Pundit Scopes

ответ

1

Я не имею большого опыта работы с pundit, однако, глядя на документацию и код код, который я могу видеть 2 вещи.

1 - Вы не должны использовать методы, подобные show? внутри вашего класса видимости.

В вашем классе видимости вы должны использовать только методы, которые возвращают область. методы, возвращающие значение boolean, должны находиться на уровне политики. Но в вашем коде я могу использовать логические методы внутри класса scope.

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 - Учитывая, что Scope являются Порос (Plain Old рубин Object) вы можете иметь более одного метода разрешать (конечно с другим именем :)), потому что решительность просто имя метода.

Может быть, вы можете сделать что-то вроде

#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 

в контроллере

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

Это должен первым авторизовать метод шоу с ArticlePolicy#show? и объемом от ArticlePolicy::Scope#resolve_show

Отказа от ответственности: Непроверенный код , используйте на свой страх и риск;)

+0

Thanks так много @ sameera207. Это заставило меня начать решать проблемы. Для других - области должны быть отделены от элементов управления действием. Области могут быть нюансированы для специфики набора данных. Элементы управления действиями должны быть способны к истинному или ложному результату (и если это правда, тогда область применения применяется). – Mel

Смежные вопросы