Consul 0.9 lets you optimize records checks

Updated . Posted . Visible to the public.

Consul 0.9 Show archive.org snapshot comes with many new features to optimize powers that only check access to a given record. e.g. Power.current.post?(Post.last). See below for details.

Powers that only check a given object

Sometimes it is not convenient to define powers as a collection. Sometimes you only want to store a method that
checks whether a given object is accessible.

To do so, simply define a power that ends in a question mark:

class Power
  ...

  power :updatable_post? do |post|
    post.author == @user
  end

end

You can query such an power as always:

power = Power.new(@user)
power.updatable_post?(Post.last) # return true if the author of the post is @user
power.updatable_post!(Post.last) # raises Consul::Powerless unless the author of the post is @user

Optimizing record checks for scope powers

You can query a scope power for a given record, e.g.

class Power
  ...

  power :posts do |post|
    Post.where(:author_id => @user.id)
  end
end

power = Power.new(@user)
power.post?(Post.last)

What Consul does internally is fetch all the IDs of the power.posts scope and test if the given
record's ID is among them. This list of IDs is cached for subsequent calls, so you will only touch the database once.

As scary as it might sound, fetching all IDs of a scope scales quiet nicely for many thousand records. There will
however be the point where you want to optimize this.

What you can do in Consul is to define a second power that checks a given record in plain Ruby:

class Power
  ...

  power :posts do |post|
    Post.where(:author_id => @user.id)
  end

  power :post? do |post|
    post.author_id == @user.id
  end

end

This way you do not need to touch the database at all.

Henning Koch
Last edit
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2013-07-19 15:18)