diff --git a/lib/pundit.rb b/lib/pundit.rb index 610419f..865bc0f 100644 --- a/lib/pundit.rb +++ b/lib/pundit.rb @@ -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 diff --git a/spec/pundit_spec.rb b/spec/pundit_spec.rb index 7de6fbf..c48e005 100644 --- a/spec/pundit_spec.rb +++ b/spec/pundit_spec.rb @@ -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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index cdbf0dd..d5be5ae 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -56,6 +56,16 @@ class Post < Struct.new(:user) def inspect; "#"; 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