diff --git a/lib/cancan/ability/strong_parameter_support.rb b/lib/cancan/ability/strong_parameter_support.rb index 31da7457..892d250a 100644 --- a/lib/cancan/ability/strong_parameter_support.rb +++ b/lib/cancan/ability/strong_parameter_support.rb @@ -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 diff --git a/spec/cancan/ability_spec.rb b/spec/cancan/ability_spec.rb index 486cbc42..3951f3b2 100644 --- a/spec/cancan/ability_spec.rb +++ b/spec/cancan/ability_spec.rb @@ -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 @@ -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