You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Granting read permission on a subset of STI subclass doesn't lead to relevant records being returned by accessible_by. With the following STI hierarchy:
Given can :read, Ferrari we expect Vehicle.accessible_by(ability, :index) to include any instances of Ferrari (but none of Suzuki), but instead no Vehicle records are returned.
Reproduction:
require'bundler/inline'gemfile(true)dosource'https://rubygems.org'gem'rails','= 6.1.7'gem'cancancan','= 3.4.0',require: false# require false to force rails to be required firstgem'sqlite3'endrequire'active_record'require'cancancan'require'minitest/autorun'require'logger'ActiveRecord::Base.establish_connection(adapter: 'sqlite3',database: ':memory:')ActiveRecord::Base.logger=Logger.new(STDOUT)ActiveRecord::Schema.definedocreate_table:vehicles,force: truedo |t|
t.string:typeendendclassVehicle < ActiveRecord::Base;endclassCar < Vehicle;endclassMotorbike < Vehicle;endclassFerrari < Car;endclassSuzuki < Motorbike;endclassAbilityincludeCanCan::Abilitydefinitializecan:read,FerrariendendclassBugTest < Minitest::Testdeftest_bugferrari=Ferrari.create!suzuki=Suzuki.create!ability=Ability.new# These assertions passassert_equaltrue,ability.can?(:index,Ferrari)assert_equalfalse,ability.can?(:index,Suzuki)# This assertion passesassert_equal[ferrari],Ferrari.accessible_by(ability,:index).to_a# This assertion also passesassert_equal[ferrari],Car.accessible_by(ability,:index).to_a# This assertion fails (the actual array is empty)assert_equal[ferrari],Vehicle.accessible_by(ability,:index).to_aendend
This seems like intentional behaviour according to this suggested test: #689 (comment) My expectation also seems to be somewhat at odds with the expectation set out in another issue: #771
My expectation was that since all Ferraris and Suzukis are Vehicles (both intuitively and in the assert_equal true, ferrari.is_a?(Vehicle) sense), asking for the set of accessible Vehicles (assuming that Ferraris but not Suzukis have been marked as accessible) should include only Ferraris.
Steps to reproduce
Granting read permission on a subset of STI subclass doesn't lead to relevant records being returned by
accessible_by
. With the following STI hierarchy:Given
can :read, Ferrari
we expectVehicle.accessible_by(ability, :index)
to include any instances ofFerrari
(but none ofSuzuki
), but instead noVehicle
records are returned.Reproduction:
This feels like an extension of #677
Expected behavior
The allowed subclass instances should be returned by
klass.accessible_by
for all klasses in the STI hierarchy.Actual behavior
The allowed subclass instances are not returned by
accessible_by
when invoked on the base class.System configuration
Rails version:
6.1.7
Ruby version:
2.7.6
CanCanCan version
3.4.0
The text was updated successfully, but these errors were encountered: