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?

--
Posted via http://www.ruby-forum.com/.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

Search Discussions

  • Frederick Cheung at Dec 6, 2011 at 5:23 pm

    On Dec 6, 4:49 pm, "Eric B." wrote:
    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?
    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
    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?

    --
    Posted viahttp://www.ruby-forum.com/.
    --
    You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
    To post to this group, send email to rubyonrails-talk@googlegroups.com.
    To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouprubyonrails-talk @
categoriesrubyonrails
postedDec 6, '11 at 4:50p
activeDec 6, '11 at 5:23p
posts2
users2
websiterubyonrails.org
irc#RubyOnRails

2 users in discussion

Eric B.: 1 post Frederick Cheung: 1 post

People

Translate

site design / logo © 2021 Grokbase