2017-05-18 2 views
0

Selon the Pundit readmeauthorize devrait retourner l'enregistrement, mais quand je l'appelle, je reçois true.Obtenir des booléens au lieu d'enregistrer lors de l'autorisation avec Pundit

authorize renvoie l'objet qui lui est passé, de sorte que vous pouvez enchaîner comme ceci:

Controller:

def show 
    @user = authorize User.find(params[:id]) 
end 

Gemfile:

gem 'rails', '~> 5.1.1' 
gem 'devise', '~> 4.3' 
gem 'pundit', '~> 1.1' 

Mon contrôleur:

class PostsController < ApplicationController 
    skip_before_action :authenticate_user!, only: [:show, :index] 
    before_action :set_post, only: [:show, :edit, :update, :destroy] 

    def show 
    # just for debugging purposes 
    raise "Post is a #{@post.class.name}!" unless @post.is_a? Post 
    end 

    def set_post 
    # this should return an instance of post 
    @post = authorize Post.find(params[:id]) 
    end 
end 

Politique:

class PostPolicy < ApplicationPolicy 

    class Scope < Scope 
    def resolve 
     scope.all 
    end 
    end 

    def show? 
    true 
    end 

    # ... 
end 

Spec:

require 'rails_helper' 
RSpec.describe "Posts", type: :request do 
    subject { response } 

    describe "GET /posts/:id" do 
    let!(:post) { create(:post) } 
    before { get post_path(post) } 
    it { should be_successful } 
    end 
end 

Échec message:

4) Posts GET /posts/:id 
    Failure/Error: raise "Post is a #{@post.class.name}!" unless @post.is_a? Post 

    RuntimeError: 
     Post is a TrueClass! 

Alors que son assez simple pour y remédier par:

def set_post 
    @post = Post.find(params[:id]).tap do |p| 
    @post = Post.find(params[:id]).tap { |r| authorize r } 
    end 
end 

Im très curieux de savoir pourquoi il ne fonctionne pas comme indiqué par le readme. Est-ce un bug ou est-ce que je manque quelque chose?

Répondre

0

Le retour de l'enregistrement est apparemment un changement dans le maître qui n'est pas reflété dans la version 1.1.

# Retrieves the policy for the given record, initializing it with the 
# record and user and finally throwing an error if the user is not 
# authorized to perform the given action. 
# 
# @param user [Object] the user that initiated the action 
# @param record [Object] the object we're checking permissions of 
# @param record [Symbol] the query method to check on the policy (e.g. `:show?`) 
# @raise [NotAuthorizedError] if the given query method returned false 
# @return [true] Always returns true 
def authorize(user, record, query) 
    policy = policy!(user, record) 

    unless policy.public_send(query) 
    raise NotAuthorizedError, query: query, record: record, policy: policy 
    end 

    true 
end 

Une solution de contournement est:

def authorize(record, query = nil) 
    super 
    record 
end