cancancan
cancancan copied to clipboard
Association is renamed in SQL and results in unknown column error
Steps to reproduce
I tried to use the gist from here to reproduce the issue, but it throws an error
CanCan::NotImplemented: This model adapter does not support fetching records from the database.when using Rails 6.1.6. So I try to explain it as good as I can:
My ability has this line
can :index, Spree::EventImage, event: { time_item: { city_zone_id: user.city_zone_ids } }
The models look like this:
module Spree
class EventImage < ApplicationRecord
belongs_to :event
end
end
module Spree
class Event < ApplicationRecord
has_one :time_item, as: :timeable, dependent: :destroy
end
end
module Spree
class TimeItem < ApplicationRecord
belongs_to :timeable, polymorphic: true
belongs_to :city_zone
end
end
Expected behavior
When I use EventImage.accessible_by(current_ability) it generates this SQL:
SELECT `spree_event_images`.* FROM `spree_event_images` WHERE `spree_event_images`.`id` IN (
SELECT `spree_event_images`.`id` FROM `spree_event_images`
LEFT OUTER JOIN `spree_events` ON `spree_events`.`id` = `spree_event_images`.`event_id`
LEFT OUTER JOIN `spree_time_items` `time_items_spree_events` ON `time_items_spree_events`.`timeable_type` = 'Spree::Event' AND `time_items_spree_events`.`timeable_id` = `spree_events`.`id`
WHERE `spree_time_items`.`city_zone_id` IN (123, 987)
)
And this results in this error
Mysql2::Error: Unknown column 'spree_time_items.city_zone_id' in 'where clause'
Actual behavior
I guess there is something wrong with the renaming of the table, but I'm not sure if it is a problem at rails or cancancan. The problematic part is this:
LEFT OUTER JOIN `spree_time_items` `time_items_spree_events`
It seems that somehow the spree_time_items table gets renamed to time_items_spree_events, but is later referenced by it's original name in the query, thus resulting in the error above.
When using Rails 6.0.4.8 this generates the following SQL which works as expected:
SELECT `spree_event_images`.* FROM `spree_event_images` WHERE `spree_event_images`.`id` IN (
SELECT `spree_event_images`.`id` FROM `spree_event_images`
LEFT OUTER JOIN `spree_events` ON `spree_events`.`id` = `spree_event_images`.`event_id`
LEFT OUTER JOIN `spree_time_items` ON `spree_time_items`.`timeable_type` = 'Spree::Event' AND `spree_time_items`.`timeable_id` = `spree_events`.`id`
WHERE `spree_time_items`.`city_zone_id` IN (123, 987)
)
System configuration
Rails version: 6.1.6
Ruby version: 2.7.2
CanCanCan version: 3.3.0
Unfortunately, I still have no solution to this and the update to cancancan 3.4.0 didn't resolve it either. Can someone help me, figuring this out?
I just tried cancancan 3.5.0 and I still have the same issue. Was hoping that this fix would also fix my issue https://github.com/CanCanCommunity/cancancan/pull/814
Can someone from the team help me figure out what's wrong here?