Acl9 find only model object that satisfies object.accepts_role? (role_name, current_user)

I am new to rails and this is the first time I am using authlogic + acl9. I followed the default installation steps for both plugins.

So far, everything is working fine, but it's hard for me to find an elegant solution to this problem:

Let's say I have a model class called Products. When creating a new Product object, I assign current_user as the owner:

current_user.has_role! :owner, @product 

I registered a second user and made sure that this part works.

In the product controller, I have an index method just returning all products:

 def index @products = Products.all end 

My question is: how can I call the find method on Products to get only those products where current_user is: the owner? Therefore, I use the acl9 interface, which will mean:

 @product.accepts_role?(:owner, current_user) 

One possibility would probably be to first get all the products and then create a new array with only current_user tags. it can be like this:

 @products = [] products = Products.all products.each do |p| @products << p if p.accepts_role?(:owner, current_user) end 

This decision seems rather wasteful. So what is the right way to do this?

Thanks everyone!

+4
source share
4 answers

how to do everything in one request:

 @products = Product.all.select { |p| p.accepts_role?(:owner, current_user)} 

but the idea remains the same as in itself

+1
source

I recently came to the same conclusion in a project that I was working on.

I was tempted to make some connections in the role tables and role_user with the product table, but ended up using the above approach.

Works well now, but it will not scale well.

0
source

I am not sure why you want to make any kind of unions. If you followed the default settings for acl9, you should have a many-to-many relationship between the user and his roles and many-to-one between the roles and each authorization object. Therefore, if you have all the relationships correctly specified in your models, you can get objects with something as simple as

current_user.roles.find(:first, :conditions => { :name => 'owner' }).products

You may need to specifically describe the products as named areas or associations in the role model, and you can simplify all this by even adding this crawler to the named area.

0
source

Add these areas to your Product model:

 scope :roled_by, -> ( r, u ) { where id: u.role_objects.select(:authorizable_id).where( :name => r, :authorizable_type => self ) } scope :owned_by, -> (u) { roled_by :owner, u } 

... and call it this: Product.owned_by current_user - you can use the same template to add as many other role areas as you want (or just call Product.roled_by :owner, current_user if you want).

Oh, and note that I used the default role_objects method, if you set it to something else (as it very often happens), change it in the scope.

0
source

All Articles