# Resources, has\_many :through and extra attributes on 'join model'

**URL:** <https://www.ruby-forum.com/t/resources-has-many-through-and-extra-attributes-on-join-model/126169>\
**Category:** Rails\
**Created:** [January 16, 2008, 12:20am UTC](https://www.ruby-forum.com/t/resources-has-many-through-and-extra-attributes-on-join-model/126169 "2008-01-16T00:20:45Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 16, 2008, 12:20am UTC](https://www.ruby-forum.com/t/resources-has-many-through-and-extra-attributes-on-join-model/126169/1 "2008-01-16T00:20:45Z")

</div>

Hi,

I found a small ‘problem’ to which I think I found a solution.  
But the solution feels a bit hacky.  
I would like some feedback on it.

Say I have Groups & Users.  
A group has many users, but a user can also belong to many groups.  
Also, the role a user has in a group should be known.

1. class Group \< ActiveRecord::Base
2. has\_many :memberships
3. has\_many :users, :through =\> :memberships
4. end
5. 
6. class User \< ActiveRecord::Base
7. has\_many :memberships
8. has\_many :groups, :through =\> :memberships
9. end
10. 
11. class Membership \< ActiveRecord::Base
12. belongs\_to :group
13. belongs\_to :user
14. validates\_uniqueness\_of :user\_id, :scope =\> :group\_id
15. 
16. 
# this model has a field “role” which describes the role a

user has in the group  
17. end

Now, this suffices for the database and the model, but in my routes  
file I don’t want to expose memberships as resources (since they are  
kind of artificial), so:

1. map.resources :groups do |group|
2. 

```
group.resources :users

```

3. end
4. 
5. map.resources :users do |user|
6. 

```
user.resources :groups

```

7. end

This works, I can now see which users are in a group(on /groups/2/  
users), but there is no way to see what role they have.

My solution would be to give users a virtual attribute (role) which  
should get filled in when they are acquired by a group.

something along the lines of

1. class Group \< ActiveRecord::Base
2. has\_many :memberships
3. has\_many :users, :through =\> :memberships
4. 
5. def users\_with\_roles
6. 

```
array = []

```

7. 

```
memberships.each do |membership|

```

8. 

```
  user = membership.user

```

9. 

```
  user.role = membership.role

```

10. 

```
  array << user

```

11. 

```
end

```

12. 

```
array

```

13. end
14. end

Now, I can use @group.users\_with\_roles in my userscontroller’s index  
action and display the list of users, including their role in this  
group.

Of course this needs some changes for finding single users also, and  
code to handle saving in case of adding users to a group.

But before I go that way I need to be assured this is the/a way to go.  
Like I said, it feels very hacky, so I guess there should be a better  
way to do this.

Any thoughts on this subject?  
Like I said, I don’t want to expose memberships to the outside world,  
just users & groups.

Thanks, Mathijs
