1
0
Fork 0
mirror of https://github.com/varvet/pundit.git synced 2022-11-09 12:30:11 -05:00

Add autodetection and override of param key for permitted_attributes helper.

First, trying to get param key for ActiveModel objects, as Rails' `form_for` helper uses it to generate key for parameters hash. See 9f44aa0863/actionview/lib/action_view/helpers/form_helper.rb (L433) for reference.

Second, allowing to redefine it with `param_key` option (as element in optional second argument hash), it is useful in case of single table inheritance, when the param key is differs from actual class (as it is getting defined at runtime).

And last, use previous behaviour otherwise.

Fixes https://github.com/elabs/pundit/issues/286
This commit is contained in:
Andrey Novikov 2015-07-13 16:56:55 +03:00
parent 7c121d5dd7
commit 12602720a5
No known key found for this signature in database
GPG key ID: 301AD540051205A2
3 changed files with 34 additions and 2 deletions

View file

@ -139,8 +139,15 @@ module Pundit
policies[record] ||= Pundit.policy!(pundit_user, record)
end
def permitted_attributes(record)
name = record.class.to_s.demodulize.underscore
def permitted_attributes(record, options={})
name = options.delete(:param_key)
name ||= if record.class.respond_to?(:model_name) # ActiveModel and ActiveRecord
record.class.model_name.param_key
elsif record.respond_to?(:model_name)
record.model_name.param_key
else
record.class.to_s.demodulize.underscore
end
params.require(name).permit(policy(record).permitted_attributes)
end

View file

@ -3,6 +3,7 @@ require "spec_helper"
describe Pundit do
let(:user) { double }
let(:post) { Post.new(user) }
let(:customer_post) { Customer::Post.new(user) }
let(:comment) { Comment.new }
let(:article) { Article.new }
let(:controller) { Controller.new(user, { :action => 'update' }) }
@ -343,6 +344,20 @@ describe Pundit do
expect(Controller.new(user, params).permitted_attributes(post)).to eq({ 'title' => 'Hello', 'votes' => 5 })
expect(Controller.new(double, params).permitted_attributes(post)).to eq({ 'votes' => 5 })
end
it "checks policy for permitted attributes for record of a ActiveModel type" do
params = ActionController::Parameters.new({ action: 'update', customer_post: { title: 'Hello', votes: 5, admin: true } })
expect(Controller.new(user, params).permitted_attributes(customer_post)).to eq({ 'title' => 'Hello', 'votes' => 5 })
expect(Controller.new(double, params).permitted_attributes(customer_post)).to eq({ 'votes' => 5 })
end
it "checks policy for permitted attributes for record with manually specified param key" do
params = ActionController::Parameters.new({ action: 'update', custom_post: { title: 'Hello', votes: 5, admin: true } })
expect(Controller.new(user, params).permitted_attributes(post, param_key: 'custom_post')).to eq({ 'title' => 'Hello', 'votes' => 5 })
expect(Controller.new(double, params).permitted_attributes(post, param_key: 'custom_post')).to eq({ 'votes' => 5 })
end
end
describe "Pundit::NotAuthorizedError" do

View file

@ -56,6 +56,16 @@ class Post < Struct.new(:user)
def inspect; "#<Post>"; end
end
module Customer
class Post < Post
def self.model_name
OpenStruct.new(param_key: 'customer_post')
end
def policy_class
PostPolicy
end
end
end
class CommentPolicy < Struct.new(:user, :comment); end
class CommentPolicy::Scope < Struct.new(:user, :scope)
def resolve