0

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.

halfer
  • 19,824
  • 17
  • 99
  • 186
pitosalas
  • 10,286
  • 12
  • 72
  • 120

1 Answers1

2

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
Community
  • 1
  • 1
mathieugagne
  • 2,465
  • 1
  • 17
  • 18
  • Thanks! Question, what's the third param on can doing? (i.e. klass.visible_to?) – pitosalas Feb 02 '13 at 20:29
  • Passes a block to the scope. Find it all here: https://github.com/ryanb/cancan/wiki/Defining-Abilities-with-Blocks Look at Block conditions with Scopes – mathieugagne Feb 02 '13 at 20:36
  • Hard to understand exactly why the third (klass.owned_by?) is needed because in the block (the fourth param) the same thing is asked again: record.owned_by? user. Can you explain? (I read the link and not quite clear yet.) – pitosalas Feb 02 '13 at 20:44
  • You were right, sorry about that. I've updated the answer. It was simply to show it was possible to pass a block to your scope which is not needed in your case. – mathieugagne Feb 02 '13 at 20:46