Users have permission to manage articles for specific combinations of location and category.
For example, Dave is allowed to manage HR personnel for Paris. Paul may be allowed to run business articles for London.
Models and their associations are as follows:
- user has many permissions
- permission belongs to user, location and category
- category contains many articles and permissions
- layout has many articles and permissions
- article relates 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} } } end
When do I call allow_to? (: delete) in an article entry (category ID 1893 and location ID 2939), the following queries are executed:
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 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.
Update
So now I 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) end
and my rule now:
has_permission_on :articles, :to => :manage do if_attribute :permitted_user_ids => contains { user.id } end
Now when do I call allow_to? (: delete) (or read / update / create / manage) in the entry of the article whose category identifier is 1893 and the location identifier is 2939, the following query is executed:
SELECT user_id FROM `permissions` WHERE `permissions`.`category_id` = 1893 AND `permissions`.`location_id` = 2939
... this is exactly what I want.
Except that the scope with_permissions_to behaves very weird.
Article.with_permissions_to(:read)
Now generated:
SELECT `articles`.* FROM `articles` WHERE (`articles`.`id` = 9473)
... where 9473 is the current user id!
I am very confused.