Comments (12)
The error occurs in this line in the #parent_child_conditions
method during iteration though reflect_on_all_associations(:belongs_to)
.
If change the order of the association definition from:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
belongs_to :user
end
to:
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :commentable, polymorphic: true
end
the issue will be resolved but it's just a temporary life hack 😄
from cancancan.
Here it is for convenience: #814
from cancancan.
This will only fix the issue if you check user attribute in your case.
But if you check Comment model field (can :read, Comment, private: true), it will fail in any case
from cancancan.
I got this error with the devise_invitable gem which adds the belongs_to :invited_by, polymorphic: true
association in Rails 6.1. Downgrading to Cancancan 3.3.0 solved it for me.
from cancancan.
The issue seems to be caused by this change:
d0ea89a#diff-468c7fa6110fedf2a4ae5259ca4d209daea99810746321092dac9cf373b87fdd
from cancancan.
I have the same issue, downgraded for now to 3.3.0
from cancancan.
The issue seems to be caused by this change: d0ea89a#diff-468c7fa6110fedf2a4ae5259ca4d209daea99810746321092dac9cf373b87fdd
Can confirm, the new offending behaviour is:
def parent_child_conditions(parent, child, all_conditions)
child_class = child.is_a?(Class) ? child : child.class
foreign_key = child_class.reflect_on_all_associations(:belongs_to).find do |association|
association.klass == parent.class
end&.foreign_key&.to_sym
foreign_key.nil? ? nil : all_conditions[foreign_key]
end
For ActiveRecord::Reflection::BelongsToReflection, 'klass' cannot be calculated for polymorphic associations so if one is utilised on the child class, the finder will error. As 'find' halts on the first instance, the temporary fix above to reoder polymorphic associations solves the issue for some.
Suggestion would be to add 'unless association.polymorphic?' to the finder to ensure polymorphic associations are ignored.
from cancancan.
Any luck with this? I am currently facing this issue and not finding a good work around so far.
from cancancan.
Unfortunately I did not implement any Work around except for downgrading to version 3.3.0.
However, with a little experimenting I found some workaround for my situation, although not ideal.
My original Ability code was:
can [:read, :update, :destroy], User, account_id: current_user.account_id
So, this one triggers the above exception with version 3.4.0.
I can rewrite it to
can [:read, :update, :destroy], User do |user|
user.account_id==current_user.account_id
end
Now the exception is gone away and the right authorization is applied to the individual records BUT there is one drawback:
now the :read does not apply to the listing anymore. In other words: @users gives me all users and not just that of the account they belong to. So, I should apply an extra filter in my controller to make it work. But that could be acceptable.
Hopes this helps for your situation.
from cancancan.
I ran into this same issue and I think I can explain why changing the order of the association works, but I don't know what the long term fix is.
The issue seems to stem from lib/cancan/model_adapters/active_record_adapter.rb#parent_child_conditions
. Look at this snippet of code:
def parent_child_conditions(parent, child, all_conditions)
...
foreign_key = child_class.reflect_on_all_associations(:belongs_to).find do |association|
association.klass == parent.class
end&.foreign_key&.to_sym
...
end
When you do something like load_and_authorize_resource through: :current_user
, it eventually ends up calling this method. This method loops through all your belongs_to
associations on the resource you're trying to use.
On each of the belongs_to
associations, it calls association.klass
and sees if it matches the parent class you're trying to load through.
The problem is this rails/rails@fb86ecd doesn't allow you to call association.klass
on polymorphic associations. So when it hits that association, the app throws an exception.
The reason the code will work if you re-arrange your associations, is that if the association you're dealing with happens to be near the top and matches BEFORE it hits a polymorphic association, the loop stops. I'm assuming .find
just stops after it's found a match. So you never hit the error of calling .klass
on a polymorphic association.
So re-arranging your associations may work - but it's quite brittle and won't work in a lot of cases.
Long term fix would be to update this loop code to handle polymorphic associations.
from cancancan.
@caseyli please see my PR linked above. It does just as you suggest and adds support for polymorphic associations.
from cancancan.
Closed on 3.5.0. Thank you!
from cancancan.
Related Issues (20)
- STI normalizer fails when existing rule conditions are relation HOT 2
- undefined method `#{parent_name}=' for singleton associations
- Nil values on enums fails to authorize
- Gemspec does not have Rails version dependency for various version of the gem
- cancancan is chaninging my get request ID HOT 1
- Deep conditions nesting on sqlite => stack overflow
- Selective permissions on STI sub-classes not respected by accessible_by HOT 1
- Granting read permission on intermediate STI table prevents any records being returned HOT 4
- inconsistent behaviour with Hash subjects
- `can?` unnecessarily loads relationships in memory when it could leverage `accessible_by` HOT 1
- can? should return false when there are no attributes that the current user can perform action on HOT 1
- Possible breaking change with handling of `nil` conditions in 3.5.0 HOT 1
- How to define ability action name that is same as the default action aliases?
- Why are merged rules still bound to the merged Ability class?
- Extra table alias is being generated, but then ignored in the final stage of an accessible_by query HOT 1
- Creating resource failes when association is polymorphic and singleton.
- Can't apply rules to `create` action without affecting `new` because of aliasing HOT 13
- Resource Loader gets ignored with Whitespace-Only ID in URL (e.g., "\n") HOT 1
- Support Rails's `attribute` in Cancancan's `permitted_attributes` HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cancancan.