Skip to content

Commit

Permalink
In permitted_attributes, switch from database column detection to Rai…
Browse files Browse the repository at this point in the history
…ls attributes detection. Addresses #838 (#839)

* In permitted_attributes, switch from database column detection to Rails attributes detection. Fixes #838

* Temporarly revert "In permitted_attributes, switch from database column detection to Rails attributes detection. Fixes #838"

This reverts commit 530a202.

Reason: Adjust tests to obtain a before and after picture

* Switch AbilitySpec's User testcase to an actual database model NamedUser in order to include Rails' actual column loading behavior

* Demonstrate that the current implementation misses model attributes created  by Rails' "attribute" call

* Re-enable fix by reverting "Temporarly revert "In permitted_attributes, switch from database column detection to Rails attributes detection. Fixes #838""

This reverts commit 1195d39.
  • Loading branch information
kalsan authored May 23, 2024
1 parent ac7c686 commit 0cdbba7
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lib/cancan/ability/strong_parameter_support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def get_attributes(rule, subject)
klass = subject_class?(subject) ? subject : subject.class
# empty attributes is an 'all'
if rule.attributes.empty? && klass < ActiveRecord::Base
klass.column_names.map(&:to_sym) - Array(klass.primary_key)
klass.attribute_names.map(&:to_sym) - Array(klass.primary_key)
else
rule.attributes
end
Expand Down
22 changes: 17 additions & 5 deletions spec/cancan/ability_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@
describe CanCan::Ability do
before(:each) do
(@ability = double).extend(CanCan::Ability)

connect_db
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table(:named_users) do |t|
t.string :first_name
t.string :last_name
end
end

unless defined?(NamedUser)
class NamedUser < ActiveRecord::Base
attribute :role, :string # Virtual only
end
end
end

it 'is able to :read anything' do
Expand Down Expand Up @@ -651,13 +666,10 @@ def active?
end

it 'returns an array of permitted attributes for a given action and subject' do
user_class = Class.new(ActiveRecord::Base)
allow(user_class).to receive(:column_names).and_return(%w[first_name last_name])
allow(user_class).to receive(:primary_key).and_return('id')
@ability.can :read, user_class
@ability.can :read, NamedUser
@ability.can :read, Array, :special
@ability.can :action, :subject, :attribute
expect(@ability.permitted_attributes(:read, user_class)).to eq(%i[first_name last_name])
expect(@ability.permitted_attributes(:read, NamedUser)).to eq(%i[id first_name last_name role])
expect(@ability.permitted_attributes(:read, Array)).to eq([:special])
expect(@ability.permitted_attributes(:action, :subject)).to eq([:attribute])
end
Expand Down

0 comments on commit 0cdbba7

Please sign in to comment.