2015-09-07 4 views
2

Моей политики для создания, обновление & уничтожения «любит» требует, чтобы пользователь вошли вПандит санкционирование текущего пользователя

Я сформулировал политику следующим образом:.

class LikePolicy < ApplicationPolicy 
    def create? 
    user && record.user_id == user.id 
    end 

    def update? 
    create? 
    end 

    def destroy? 
    create? 
    end 
end 

понравившихся # создать контроллер действие заключается в следующем:

def create 
    @article = Article.find(params[:article_id]) 
    @like = @article.likes.new(user_id: current_user.id, value: params[:value] == 1 : 1 ? -1) 
    authorize(@like) 
    @like.save 
    redirect_to @article 
end 

Это работает, однако с помощью политики, чтобы подтвердить, что пользователь вошел в нелогично, как код потерпит неудачу на предыдущий, как где Curre Ссылка на nt_user.

Является ли это принятой практикой для авторизации записей, которые включают user_id?

ответ

3

Обычно я хотел бы проверить, что пользователь вошел в систему с помощью отдельной проверки подлинности. Если ваше приложение в основном требует, чтобы пользователь был подписан, а затем выполнив проверку подлинности перед авторизацией, вы всегда будете иметь current_user.

Также для создания я обнаружил, что мне не нравится идея вызова new/authorize/save, чтобы убедиться, что пользователь создает объект, принадлежащий им. Это логика приложения, которая действительно не имеет никакого отношения к авторизации. Вместо этого для создания вы можете просто пройти в классе, Pundit не против.

В зависимости от того, выполняете ли вы проверку подлинности сначала, авторизация может просто вернуть значение true, или вы можете проверить на !user.nil.

Последнее, что я нашел полезным с Pundit, - это попытаться абстрагировать логику в несколько самостоятельных документирующих методов. Это упрощает чтение политик-экспертов, а также позволяет абстрагировать логику вплоть до ApplicationPolicy или включать их через модули. В приведенном ниже примере is_owner? может быть легко абстрагирован, поскольку он может использоваться во многих ситуациях.

Пример 1: аутентифицировать затем Авторизуйте

class LikesController 
    # Either from devise, or define in ApplicationController 
    before_action :authenticate_user! 

    def create 
    authorize(Like) 
    article = Article.find(params[:article_id]) 
    article.likes.create(user_id: current_user.id, ...) 
    redirect_to article 
    end 
end 

class LikePolicy < ApplicationPolicy 
    def create? 
    true 
    end 

    def update? 
    is_owner? 
    end 

    def destroy? 
    is_owner? 
    end 

    private 

    def is_owner? 
    user == record.user 
    end 
end 

Пример 2: Только Авторизовать

class LikesController 
    def create 
    authorize(Like) 
    article = Article.find(params[:article_id]) 
    article.likes.create(user_id: current_user.id, ...) 
    redirect_to article 
    end 
end 

class LikePolicy < ApplicationPolicy 
    def create? 
    !user.nil? 
    end 

    def update? 
    is_owner? 
    end 

    def destroy? 
    is_owner? 
    end 

    private 

    def is_owner? 
    user && user == record.user 
    end 
end 
+0

большую обратную связь. – Dercni