How to use cancan (1.6) with STI? #746

Open
the8472 opened this Issue Sep 20, 2012 · 3 comments

Comments

Projects
None yet
3 participants

the8472 commented Sep 20, 2012

class A < ActiveRecord::Base; end
class B < A; end
class C < A;end

can :read, B, :status => :active
can :read, C, :user_id => @user.id

A.accessible_by(current_ability)

I basically want all instances of A that a user can access and restrict access to some subclasses, possibly with different criteria for the different subclasses, but this doesn't seem to be working.

What's the correct way to do it?

Collaborator

mikepack commented Sep 26, 2012

What's the error you're getting? This commit should have fixed STI.

Although your code looks relatively straightforward and should work, to simplify this test case, can you please retry this after removing all references to class C? Please limit the test case to just class A and B, using STI. Further, try reducing your role permissions by removing conditionals.

In other words, does this work?

class A < ActiveRecord::Base; end
class B < A; end

can :read, B

Does this (adding conditions)?

class A < ActiveRecord::Base; end
class B < A; end

can :read, B, :status => :active

the8472 commented Sep 26, 2012

This commit should have fixed STI.

No, as it covers the case where you grant permissions for one class and then try to access its subclass.

What I'm doing is granting access for a subclass and then trying to access the ancestor.

Essentially

can :index, B should be equivalent to

can :index, A, :type => (B.descendants.map(&:name) << B.name)  do |obj|
  obj.is_a? B
end

The issue for me is the accessible_by, which would have to lookup all permissions for subclasses and then convert them to conditions.

E.g.

class A; end
class B < A; end
class C < B; end

can :index, B, :status => nil
can :index, A, :status => :active

A.accessible_by(...)

should result in SELECT ... WHERE (type in("B", "C") and status is NULL) or status = 'active'

At least that's how I wanted to use it.

xhoy commented Jul 1, 2014

Thanks for your submission! The ryanb/cancan repository has been inactive since Sep 06, 2013.
Since only Ryan himself has commit permissions, the CanCan project is on a standstill.

CanCan has many open issues, including missing support for Rails 4. To keep CanCan alive, an active fork exists at cancancommunity/cancancan. The new gem is cancancan. More info is available at #994.

If your pull request or issue is still applicable, it would be really appreciated if you resubmit it to 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