2015-02-16 2 views
3

В одном из моего проекта я начал с помощью Пандит камень и у меня есть очень просто политика, которая выглядит следующим образом:Как сделать политику pundit более сухим?

class CompanyPolicy < ApplicationPolicy 
    def index? 
    true if user.is_a? Administrator 
    end 

    def new? 
    true if user.is_a? Administrator 
    end 

    def create? 
    new? 
    end 

    def edit? 
    true if user.is_a? Administrator 
    end 

    def update? 
    edit? 
    end 
end 

И вопрос, как я могу избежать повторения этого:

true if user.is_a? Administrator 
+0

попробуйте использовать 'before_filter' и назовите его по всем вышеперечисленным методам – Deep

+0

Это класс политики pundit, а не контроллер, и я не могу использовать before_filter ... –

ответ

3

я трюк, который выглядит следующим образом:

class ApplicationPolicy 

    private 

    def self.permit_owner_to(*actions) 
    actions.each do |action| 
     define_method("#{action}?") do 
     owner? 
     end 
    end 
    end 

    def owner? 
    # owner logic 
    end 

end 

и использовал его в других политиках

class ItemPolicy < ApplicationPolicy 

    permit_owner_to :show, :update, :destroy, :confirm 

end 
+0

Очень приятно, спасибо :) –

2

На самом деле я не думаю, что вам нужно удалить это. Повторяя это, вы явно заявляете, что этот пользователь должен быть администратором для доступа к этому методу. Если бы вы этого захотели, вы могли бы просто создать частный метод.

class CompanyPolicy < ApplicationPolicy 
    def index? 
    admin? 
    end 

    def new? 
    admin? 
    end 

    def create? 
    new? 
    end 

    def edit? 
    admin? 
    end 

    def update? 
    edit? 
    end 

    private 
    def admin? 
     user.is_a? Administrator 
    end 
end 

Угадайте, что это вопрос личных предпочтений.

+0

Сохраняя этот тест на всей базе кода, вы рискуете большим проблема, если/когда вы решите реализовать тест по-другому. Например, что, если вы решили иметь администратора _role_, а не администратора _class_? Много рефакторинга. – AndyV

0

Вы можете использовать alias_method.

class CompanyPolicy < ApplicationPolicy 
    def index? 
    user.is_a? Administrator 
    end 

    alias_method :create?, :index? 
    alias_method :update?, :index? 
end 

У вас есть базовый класс ApplicationPolicy, который, вероятно, уже содержит:

def new? 
    create? 
end 

def edit? 
    update? 
end 

так что вам не нужно повторять эти методы в подклассе.

.is_a? возвращает true или false, поэтому нет необходимости явно возвращать true if true.

Это намного более сжатый а? :)

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