# Combine two has\_and\_belongs\_to\_many

**URL:** <https://www.ruby-forum.com/t/combine-two-has-and-belongs-to-many/185159>\
**Category:** Rails\
**Created:** [March 15, 2010, 12:15pm UTC](https://www.ruby-forum.com/t/combine-two-has-and-belongs-to-many/185159 "2010-03-15T12:15:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![eugenio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ec9cab/32.png) [@eugenio](https://www.ruby-forum.com/u/eugenio)\
**Post date:** [March 15, 2010, 12:15pm UTC](https://www.ruby-forum.com/t/combine-two-has-and-belongs-to-many/185159/1 "2010-03-15T12:15:59Z")

</div>

a “User” has\_and\_belongs\_to\_many “Roles”  
a “Role” has\_and\_belongs\_to\_many “Rights”

how can i relate Users and Rights? i would like something like  
@user.rights  
i know it can be done via SQL, but i don’t know if there is a more  
rails-way to do this.  
any suggestion?  
thanks.

---

<div class="post-metadata">

**Author:** ![eugenio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ec9cab/32.png) [@eugenio](https://www.ruby-forum.com/u/eugenio)\
**Post date:** [March 15, 2010, 1:45pm UTC](https://www.ruby-forum.com/t/combine-two-has-and-belongs-to-many/185159/2 "2010-03-15T13:45:32Z")

</div>

On 15 March 2010 11:14, eugenio [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> a “User” has\_and\_belongs\_to\_many “Roles”  
> a “Role” has\_and\_belongs\_to\_many “Rights”
> 
> how can i relate Users and Rights? i would like something like  
> @user.rights  
> i know it can be done via SQL, but i don’t know if there is a more  
> rails-way to do this.

What do you mean by how to relate them? As you have defined it then  
if you have a user, @user, then @user.roles will give you an array of  
roles and @user.role[0].rights will give you an array of rights for  
that role.

Colin

---

<div class="post-metadata">

**Author:** ![eugenio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ec9cab/32.png) [@eugenio](https://www.ruby-forum.com/u/eugenio)\
**Post date:** [March 15, 2010, 1:53pm UTC](https://www.ruby-forum.com/t/combine-two-has-and-belongs-to-many/185159/3 "2010-03-15T13:53:09Z")

</div>

On 15 March 2010 11:14, eugenio [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> a “User” has\_and\_belongs\_to\_many “Roles”  
> a “Role” has\_and\_belongs\_to\_many “Rights”
> 
> how can i relate Users and Rights? i would like something like  
> @user.rights  
> i know it can be done via SQL, but i don’t know if there is a more  
> rails-way to do this.  
> any suggestion?

you can add a “rights” method to your user that collects up all the  
rights for all of the User’s roles:

def rights  
roles.collect { |role| role.rights }.flatten.uniq  
end

This gives you a starting point… you can memoize that method if you  
access it a lot, or tweak it however suits…

HTH  
Michael

---

<div class="post-metadata">

**Author:** ![eugenio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ec9cab/32.png) [@eugenio](https://www.ruby-forum.com/u/eugenio)\
**Post date:** [March 15, 2010, 3:06pm UTC](https://www.ruby-forum.com/t/combine-two-has-and-belongs-to-many/185159/4 "2010-03-15T15:06:55Z")

</div>

On 15 Mar, 13:51, Michael P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> you can add a “rights” method to your user that collects up all the  
> rights for all of the User’s roles:
> 
> def rights  
> roles.collect { |role| role.rights }.flatten.uniq  
> end
> 
> This gives you a starting point… you can memoize that method if you  
> access it a lot, or tweak it however suits…  
> thanks. i will try this, but i’m searching for something that can be  
> used with some named\_scope (based on the rights).

---

<div class="post-metadata">

**Author:** ![eugenio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ec9cab/32.png) [@eugenio](https://www.ruby-forum.com/u/eugenio)\
**Post date:** [March 15, 2010, 3:58pm UTC](https://www.ruby-forum.com/t/combine-two-has-and-belongs-to-many/185159/5 "2010-03-15T15:58:25Z")

</div>

On 15 March 2010 14:05, eugenio [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> thanks. i will try this, but i’m searching for something that can be  
> used with some named\_scope (based on the rights).

It would help if you mentioned that in your first post then, rather  
than just asking how to determine @users.rights…

I tend to use something like this in my models:

named\_scope :for\_user, lambda { |user| scope\_hash\_for\_user(user) }

private  
def self.scope\_hash\_for\_user(user)  
case (user.role rescue nil)  
when :admin  
# see everything  
when :client  
# see nothing  
{ :conditions =\> [“1 = 0”] }  
when :customer\_admin  
# their company and below  
{ :conditions =\> [“groupable\_entities.id IN (SELECT company.id  
FROM groupable\_entities AS company  
WHERE company.id in (?))”,  
user.company.self\_and\_descendants\_ids] }  
when :customer  
# their company  
{ :conditions =\> [“groupable\_entities.id IN (SELECT company.id  
FROM groupable\_entities AS company  
WHERE company.id = ?)”, user.company.id] }  
else  
raise Aegis::PermissionError, “Unknown role”  
end  
end

In the controller I can call Model.for\_user(current\_user) to return  
the items they are permitted to see, and combine it with Aegis for  
permissions-checking on specific instances of objects in controllers  
and views. Speaking to the developers of Aegis, they’re hoping to  
introduce some named-scope permissions method in their next release,  
but depending on the timescale, I might look to see if CanCan handles  
the problem better.
