with_permission_to confusion

Skip to first unread message


Dec 22, 2012, 2:17:27 PM12/22/12
to declarative_...@googlegroups.com

Users have permission to manage articles for particular combinations of location and category.

For example Dave may be allowed to manage HR articles for Paris. Paul may be allowed to manage Business articles for London.

The models and their associations are as follows:

  • user has many permissions
  • permission belongs to user, location and category
  • category has many articles and belongs to permission
  • location has many articles and belongs to permission
  • article belongs to location and category

I can say:

has_permission_on :articles, :to => :manage do
  if_attribute :location => { :permissions => { :user_id => is {user.id} }, :category => { :permissions => { :user_id => is {user.id} } }

When I call permitted_to?(:delete) on an article record (whose category id is 1893 and location id is 2939), the following queries are run:

SELECT `categories`.*  FROM `categories`  WHERE `categories`.`id` = 1893 LIMIT 1
SELECT `permissions`.* FROM `permissions` WHERE (`permissions`.category_id = 1893)
SELECT `locations`.*   FROM `locations`   WHERE `locations`.`id` = 2939 LIMIT 1
SELECT `permissions`.* FROM `permissions` WHERE (`permissions`.location_id = 2939)

What I need to be run is really:

SELECT `permissions`.* FROM `permissions` WHERE (`permissions`.category_id = 1893 AND `permissions`.location_id = 2939)

Is there any way to achieve this?

Thanks in advance.


Ok, so I now have an instance method in the article model:

def permitted_user_ids
  Permission.select('user_id').where(:location_id => location_id, :category_id => category_id).map(&:user_id)

and my rule is now:

has_permission_on :articles, :to => :manage do
  if_attribute :permitted_user_ids => contains { user.id }

Now when I call permitted_to?(:delete) (or read/update/create/manage) on an article record whose category id is 1893 and location id is 2939, the following query is run:

SELECT user_id FROM `permissions` WHERE `permissions`.`category_id` = 1893 AND `permissions`.`location_id` = 2939

...which is exactly what I want.

Except, that the with_permissions_to scope is behaving very oddly.


Now generates:

SELECT `articles`.* FROM `articles` WHERE (`articles`.`id` = 9473)

...where 9473 is the ID of the current user!

I am very confused.

I've read steffenb's comments in in this post which makes me think this is a known shortcoming but I can't help think I've missed something obvious.

Reply all
Reply to author
0 new messages