Open
Description
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:
class Vehicle < ActiveRecord::Base
class Car < Vehicle
class Motorbike < Vehicle
class Ferrari < Car
class Suzuki < Motorbike
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) do
source 'https://rubygems.org'
gem 'rails', '= 6.1.7'
gem 'cancancan', '= 3.4.0', require: false # require false to force rails to be required first
gem 'sqlite3'
end
require '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.define do
create_table :vehicles, force: true do |t|
t.string :type
end
end
class Vehicle < ActiveRecord::Base; end
class Car < Vehicle; end
class Motorbike < Vehicle; end
class Ferrari < Car; end
class Suzuki < Motorbike; end
class Ability
include CanCan::Ability
def initialize
can :read, Ferrari
end
end
class BugTest < Minitest::Test
def test_bug
ferrari = Ferrari.create!
suzuki = Suzuki.create!
ability = Ability.new
# These assertions pass
assert_equal true, ability.can?(:index, Ferrari)
assert_equal false, ability.can?(:index, Suzuki)
# This assertion passes
assert_equal [ferrari], Ferrari.accessible_by(ability, :index).to_a
# This assertion also passes
assert_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_a
end
end
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
Metadata
Metadata
Assignees
Labels
No labels