ruby-on-railsrubycancan

Duck Typed Cancan scenario


Here's my Ability.initialize:

user ||= User.new # handle guest user

if user.has_role? :admin
    can :manage, :all
elsif user.has_role? :moderator
    can :read, :all
    can :update, :all do |clazz|
        clazz.managed_by? user
    end
elsif user.has_role? :participant
    can :update, :all do |clazz|
        clazz.owned_by? user
    end
    can :read, :all do |clazz|
        clazz.visible_to? user
    end
else
    raise "Role decoding in Ability fell through"
end

My intention is that the key domain classes [User, Round, Participant, Question and Program] all define an owned_by?, managed_by? and a visible_to? method. And that the rules for allowing one of them to be updated or viewed are applied uniformly.

But I believe that statements like:

    can :update, :all do |clazz|
        clazz.owned_by? user
    end

Are not doing what I think because I don't think I even get to the clazz.owned_by? line.

What can I try next? I looked at the doc and couldn't really connect what it was saying with the technique I am using.


Solution

  • I believe :all is simply a symbol and not an iterator through all classes. You can either list them all explicitly like I'm doing here or use this solution to get a list of all models: https://stackoverflow.com/a/516605/2033014

    [User, Round, Participant, Question, Program].each do |klass|
      can :update, klass, klass.owned_by?(user)
      can :read, klass, klass.visible_to?(user)
    end