根据the Pundit readme authorize
应该返回记录,但是当我调用它时,我得到true
。
authorize返回传递给它的对象,因此你可以将它链接起来 这样:
控制器:
def show @user = authorize User.find(params[:id]) end
的Gemfile:
gem 'rails', '~> 5.1.1'
gem 'devise', '~> 4.3'
gem 'pundit', '~> 1.1'
我的控制器:
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
策略:
class PostPolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.all
end
end
def show?
true
end
# ...
end
规格:
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
失败消息:
4) Posts GET /posts/:id
Failure/Error: raise "Post is a #{@post.class.name}!" unless @post.is_a? Post
RuntimeError:
Post is a TrueClass!
虽然通过以下方式解决这个问题非常简单:
def set_post
@post = Post.find(params[:id]).tap do |p|
@post = Post.find(params[:id]).tap { |r| authorize r }
end
end
我非常好奇为什么它不能像自述文件那样工作。这是一个错误还是我错过了什么?
答案 0 :(得分:0)
返回记录显然是主人的变化,未在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
解决方法是:
def authorize(record, query = nil)
super
record
end