0

I have a model User and a model Group, between the two I want to create a many-to-many association with a join-table, using through.

user.rb:

class User < ActiveRecord::Base
    has_many :groups_user
    has_many :groups, :through => :groups_user
end

group.rb:

class Group < ActiveRecord::Base
  has_many :groups_user
  has_many :users, :through => :groups_user
end

groups_user.rb

class GroupsUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

I initially tried to do the same thing naming the joining model class GroupsUsers in groups_users.rb but I got an uninitialized constant error unless I used :class_name to specify the class name.

My question is: What is the logic behind pluralizing the first name, but not the second? The association is many-to-many so both models are on equal footing. In this case group comes first merely because of the lexical order. So why pluralize one and not the other? This makes no sense to me.

Alexander Rechsteiner
  • 5,694
  • 5
  • 34
  • 47

1 Answers1

1

The more conventional naming approach would be:

#user.rb:
class User < ActiveRecord::Base
    has_many :group_users
    has_many :groups, :through => :group_users
end

#group.rb:
class Group < ActiveRecord::Base
  has_many :group_users
  has_many :users, :through => :group_users
end

#group_user.rb
class GroupUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

Conventionally, the model has the singular form. So GroupsUser, not GroupsUsers. But, an instance of the join model has only one Group and one User, So, GroupUser, not GroupsUser.

If you look at the The has_many :through Association section of the Active Record Associations guide, for instance, you will see that the join model (Appointment) is singular. This is the pattern you want to follow.

If you decide to do things unconventionally, then rails needs you to help it - for instance by requiring that you specify class_name.

jvillian
  • 19,953
  • 5
  • 31
  • 44
  • When doing this I'm getting an SQL error because my table is called groups_users which is apparently the conventional name for the join table according to this https://stackoverflow.com/questions/11590469/rails-naming-convention-for-join-table – Alexander Rechsteiner Nov 01 '19 at 16:43
  • 2
    If you click through to the link on the Q&A you reference, you will see that the accepted answer follows the pattern I suggest. I believe (but am not 100% sure) you will find that plurals in the join table are the convention when using the `has_and_belongs_to_many` association. (Which I never use.) But, you're not using that association. You're using `has_many :through`. See link I provided in updated answer. – jvillian Nov 01 '19 at 16:53