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.
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