polymorphic nesting #73

dgm opened this Issue May 21, 2010 · 14 comments


None yet

5 participants


As I understand it, load_and_authorize_resource currently accepts an array as a deeply nested parameter, but I would like to see polymorphic nesting:
class Comment ....
load_and_authorize_resource :nested => [ { :group => :author} , :articles, :authors ]

This would allow for:


I think this needs to be looked at with issue #44 - I think the association name would be appropriate too.


I do agree CanCan needs to handle polymorphic associations better with regard to nesting, however I don't know the best way to do it. The :nested option can get very complex.

CanCan was never intended to be a full-featured resource loader. There are others out there such as Inherited Resource, and it would be nice for CanCan to interface with these full-featured resource loaders better to handle more complex cases.

I would also like to experiment with the idea of creating a custom class to handle complex resource loading. If anyone has ideas on how to handle this better I'd love to hear it!


support multiple resources in :through option of load_resource, this makes polymorphic associations possible - closed by 6998e8b


The way nesting works will change a lot in CanCan 1.3. This allows for some complex nesting which wasn't before possible. I've also added support for polymorphic associations. What you're trying to accomplish above should be possible like this with 1.3.

load_and_authorize_resource :article
load_and_authorize_resource :group
load_and_authorize_resource :author, :through => :group
load_and_authorize_resource :comment, :through => [:article, :author, :group]

If multiple options are given in :through it will use the first resource it comes across.


The problem with this is that it actually tries to load and authorize both :article and :group (correct?). If load_resource doesn't find one of the potential parent's IDs in @params, authorize_resource will check the user's ability on the class.

This breaks things when you have users that may be authorized to access one of the polymorphic parent types but not the other. Using your example scenario, a user could exist that is allowed to read comments on articles, but not on groups - unfortunately, with Cancan's current handling of polymorphic resources, you can't. It's access to all potential parents or nothing.

Seems like it should only look for the polymorphic parent (or use its class) for the parent represented by the request path.


Good point, I'll look into a solution for this problem.


What about matching the :through array syntax in some fashion? Like this:

load_and_authorize_resource [:article, :group, :author => :group]     # or [:article, {:author => :group}, :group] to exactly match your example a few comments ago
load_and_authorize_resource :comment, :through => [:article, :group, :author]

Maybe giving the first LAAR call an explicit :polymorphic => true would make it easier to parse (logically) as well.


the resource list in the array can be used along with reflection on their objects to find a matching foreign_key. once you find a foreign key that was included in params, then try to create it.


dgm: Are you suggesting getting rid of the initial (belongs_to) load_and_authorize_resource and only relying on the LAAR with :through? (Also, vote up this ticket to give it more weight)

ryanb: What are you thoughts on this? I think you recently tagged it with "Research"


The problem with using reflection is that it's heavily tied to Active Record. We'd have to add an adapter for various other ORMs (Mongoid, DataMapper, etc.) which currently (I think) just work out of the box because CanCan's interface to them is simple. I haven't had a chance to research this more though.


It's been a couple months: Wondered if you've thought more about this?

Also, what about InheritedResource's optional polymorphic associations so that these routes would both work:


I haven't tested it yet so maybe it's possible already (and I'm off to do so)


There is now a model adapter layer in CanCan 1.5 so it's possible to do more with association reflection when ActiveRecord is used. I'll be revisiting each of the issues before CanCan 2.0 to see if I can get them in for that.

There is an Inherited Resource file where you can put things specific to Inherited Resource as well. Feel free to fork the project and experiment with various solutions and comment here if you find something.


With issue #44 closed, can we close this ticket?


I'm not using cancan right now, so I have no way to evaluate.


Dear submitter, Since cancan/raynB hasn't been active for more than 6 months and no body else then ryam himself has commit permissions the cancan project is on a stand still.
Since cancan has several issues including missing support for rails 4 cancan is moving forward to cancancan. More details on: #994

If your feel that your pull request or bug is still applicable (and hasn't been merged in to cancan) it would be really appreciated if you would resubmit it to cancancan (https://github.com/cancancommunity/cancancan)

We hope to see you on the other side!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment