Database Issue

So I’m having an interesting issue with my database and associations.

I have three models, Users, Groups, and Roles. They are connected via
a join table that has user_id, group_id, and role_id on the same table.
A user is in a group, with a role. The same user can be in another
group with another (or the same) role.

So, the user model has a has_and_belongs_to_many :roles, and the role
model has a has_and_belongs_to_many :users, with the appropriate tags to
make it work.

With this, @user.roles will grab a list of all roles associated with
that user, and @role.users will grab all the users that have that role.
Duplicates are possible.

One interesting behavior, was that, if the user and the role model both
had a group_id column, then when @user.roles was called (and likewise
@role.users), it would grab the group_id from the join_table for each
role, instead of the group_id from users or roles. If I take out the
group_id from users and roles, then it does not appear when I call
@user.roles

This behavior is desirable, because then it lets me do things like,

@user.roles[@user.roles.index{|x| x.group_id==1}].name

to get the name of the role that the user has in group 1. Things like
that.

So my question is, how can I get that functionality (grabbing the
group_id when going through the join table) without the group_id columns
in the user and role tables?

I’ve tried declaring group_id as attr_accessor :group_id for both user
and role, but that didn’t work.

The most important thing is being able to maintain the behavior, that I
can call @user.roles[0].group_id, and @roles.user[0].group_id, with
group_id being grabbed from the join table. Any way to do that would
solve my problem.

Is there a way I can do it with definitions? like def
self.Role.group_id or something like that?

On Dec 6, 4:49pm, “Eric B.” [email protected] wrote:

@user.roles[@user.roles.index{|x| x.group_id==1}].name

to get the name of the role that the user has in group 1. Things like
that.

So my question is, how can I get that functionality (grabbing the
group_id when going through the join table) without the group_id columns
in the user and role tables?

There are two things at play here. The first is that the output of
inspect (which is what you see in the rails console) never includes
columns that aren’t on the original table. You can still get at them
by doing some_role.group_id.
The second thing is related to how a habtm association is loaded What
happens is that the sql that rails uses to grab your data looks
something like

select * from roles
inner join some_join_table on …
where some_join_table.user_id = 123

Rails grabs all the columns that come out of here but it only looks at
the column name, not the table name, so if multiple tables have
group_id columns they will shadow each other. Results are in theory
unpredictable. I’d avoid that situation - either don’t have the
shadowing situation or add a select option to your
has_and_belongs_to_many call that will control which columns are used.

The last thing is that most folks use has_many :through for this sort
of thing - stuff just works out nicer when the join table is an actual
model that you can play with

Fred