When dealing with data using Rails, such an opportunity rarely comes (in most cases it can be replaced by another method etc.), but since it was necessary to put an association from the intermediate table for some reason, it is a memo as a memorandum I will leave it.
class User < ApplicationRecord
has_many :group_users
has_many :groups, through: :group_users
has_many :comments
end
class Group < ApplicationRecord
has_many :group_users
has_many :users, through: :group_users
has_many :comments
end
class Comment < ApplicationRecord
belongs_to :user
belongs_to :group
end
class GroupUser < ApplicationRecord
belongs_to :group
belongs_to :user
end
Suppose a class like this exists. Normally, you rarely do anything starting from an intermediate table called GroupUser, and even if you do, you can get Comments via User or Group, so there is almost no problem.
On the other hand, there were times when I wanted a list of comments that narrowed down groups and users from an instance of GroupUser due to rare circumstances such as using GraphQL or wanting data that was arranged at the timing of an association.
If you try to get through normally, the code will be as follows, for example.
class GroupUser < ApplicationRecord
belongs_to :group
belongs_to :user
has_many :comments, through: :user #group is fine
end
However, with this method, the value of one of the through columns will be narrowed down, but the other column will not be narrowed down.
Regardless of which way you pass through, you can only narrow down by either user or group, and you cannot get the intended value.
Then what to do is to use socpe.
class GroupUser < ApplicationRecord
belongs_to :group
belongs_to :user
has_many :comments,->(group_user) { where(group_id: group_user.group_id) }, through: :user #If group, where with user
end
has_many can only take itself as a scope argument. So, by doing this, you can get a list of comments with the group_id and user_id of the group_user instance.
I hope it will be useful if you have to get it from the intermediate table as a starting point.
Recommended Posts