has_many through help, what am I doing wrong?
My models are like this:
User
has_and_belongs_to_many :Roles
Role
has_and_belongs_to_many :Users
tables:
roles_users
user_id
role_id
roleGroups
id
role_id
some_column
Now I want to create another association on the User model, that will be a collection of all roleGroups the user belongs to.
i.e. if the user is in roles with id's 1 and 2, then fetch all RoleGroups where role_id = 1 and 2.
I think I need to use a through because it is based on the user's Role association right?
I tried:
User
has_many :RoleGroups, :through => :Roles
Role
has_many :RoleGroups, :through => :User
But 开发者_JAVA技巧I get an error saying:
ActiveRecord::HasManyThroughSourceAssociationMacroError: Invalid source reflection macro :has_many :through for has_many :RoleGroups, :through => :Roles. Use :source to specify the source reflection.
Update Ok my models look like this now:
User
habtm :Roles
has_many :RoleGroups, :through => :Roles
Role
habtm :Users
has_many :RoleGroups
RoleGroup
belongs_to :Role
mysql tables:
roles_users
user_id
role_id
role_groups
id
role_id
col3
col4
..
If I do:
u = User.find(1)
u.Roles (works fine)
u.RoleGroups #see error
Error message:
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'roles.user_id' in 'where clause': SELECT `role_groups`.* FROM `role_groups` INNER JOIN `roles` ON `role_groups`.role_id = `roles`.id WHERE ((`roles`.user_id = 1))
You're looking for the has_and_belongs_to_many
association.
You can't do this the way you're thinking. I'm not sure why you're capitalizing your associations, but there are a few other things wrong, too.
First, RoleGroups
hangs off of Role
(via has_many
, but more on that in a sec), which means you don't have a direct connection between User
and RoleGroup
.
Second, it appears from your updated explanation that each RoleGroup
can have more than one Role
, which is normal, but in your code Role has_many :role_groups
, which means each role can have more than one role group. This is counterintuitive naming, but perhaps intentional. I'm going to assume that your role groups contain multiple roles rather than the other way around.
Third, you can't use a HABTM as a :through
model. HABTM only uses a table in the database, not a Rails model, so the information in your roles_users
table can't be used directly; has_many :foos :through => :bars
requires an actual Bar
model.
# Models
User
habtm :roles
Role
habtm :users
belongs_to :role_group # add role.role_group_id attribute
RoleGroup
has_many :roles # remove role_groups.role_id attribute
# Console
u = User.find(1) # get user
r = u.roles # get user roles
u.roles.collect { |role| role.role_group.name }
# ["Administrative","Editorial","User"]
精彩评论