cancan icon indicating copy to clipboard operation
cancan copied to clipboard

The can? and cannot? call cannot be used with a raw sql 'can' definition.

Open meetwudi opened this issue 10 years ago • 9 comments

My shop model and user have many-to-many relationship. Only the user belongs to the shop can manage the shop.

I followed instructions here in order to use scope.

shop.rb
scope :user_owns, ->(user_id) { joins(:shops_users).where(:shops_users => {:user_id => user_id}) }
ability.rb
can :manage, Shop, Shop.user_owns(user.id)

But I got

The can? and cannot? call cannot be used with a raw sql 'can' definition. The checking code cannot be determined for :index Shop(id: integer, name: string, description: string, description_detail: text, created_at: datetime, updated_at: datetime, feature_image_file_name: string, feature_image_content_type: string, feature_image_file_size: integer, feature_image_updated_at: datetime)

Is it a bug? I totally followed the documentation.

meetwudi avatar Dec 25 '14 12:12 meetwudi

having the same issue...

evilbikes79 avatar Jul 23 '15 17:07 evilbikes79

Are you using can? to check? or accessible_by?

Senjai avatar Jul 23 '15 17:07 Senjai

I am not using any calls to "Can?"

I have the following code in my Customer.rb model

scope :for_provider, -> (provider_id) { where("provider_id = ? OR id IN (SELECT customer_id FROM customers_providers WHERE provider_id = ?)", provider_id, provider_id) }

and the following code in my Ability.rb

can action, Customer, Customer.for_provider

evilbikes79 avatar Jul 23 '15 17:07 evilbikes79

Where does the exception occur.

MyAbility.new(user).can action, Customer, Customer.for_provider(some_id) ?

This looks like something in your application is checking for a permission on a customer, with an instance of customer, that cannot be authorized with sql since you already have that instnace.

Senjai avatar Jul 23 '15 18:07 Senjai

@tjwudi @evilbikes79 I had the same issue recently. This is what I found (I realize this is an old issue but it's never too late to share the solution): Instead of writing can :manage, Shop, Shop.user_owns(user.id) write can :manage, Shop, id: Shop.user_owns(user.id).map { |shop| shop.id }

shubhpatel108 avatar May 24 '16 15:05 shubhpatel108

@shubhpatel108 good solution, but better to use pluck instead of map method.

kenjione avatar Jun 23 '16 09:06 kenjione

@ryanb the document is need to be update!

qx avatar Mar 30 '17 06:03 qx

@qx This extension is no longer maintained.

Senjai avatar Mar 31 '17 20:03 Senjai

be aware of "plucking" and "mapping" a large amount of data. it could lead to memory bloat

simonfranzen avatar Apr 06 '21 16:04 simonfranzen