-[Create an intermediate table because it is many-to-many](#Create an intermediate table because it is many-to-many)
-[Think model in two (important here)](# Think model in two here important)
-[(1) Think from the perspective of the follower](#Think from the perspective of the follower)
-[② Think from the perspective of the follower](#Think from the perspective of the follower)
For the past few days, I've had a hard time understanding the follow function association, but I've finally managed to put it into myself, so I'll leave it as a memorandum.
Personally, I got confused at the ** description of the association to the User model **, so I mainly write about it. So this time, I haven't touched on the implementation of view and controller.
So I will start immediately.
Because the follow function association is a many-to-many (user-to-user) association, It is necessary to prepare an intermediate table and make it a "one-to-many" (user-to-relationships) association.
(For those who like one-to-many or many-to-many, [[for beginners] Rails "association" tutorial that is too polite [anything] [perfectly understood]](https://qiita.com/kazukimatsumoto/items/14bdff681ec5ddac26d1 #% E3% 83% 95% E3% 82% A9% E3% 83% AD% E3% 83% BC% E3% 83% 95% E3% 82% A9% E3% 83% AD% E3% 83% AF% E3% 83% BC% E6% A9% 9F% E8% 83% BD% E3% 82% 92er% E5% 9B% B3% E3% 82% 92% E4% BD% BF% E3% 81% A3% E3% 81% A6% E8% A8% AD% E8% A8% 88% E3% 81% 97% E3% 82% 88% E3% 81% 86) I recommend this article too. I learned.)
So, first create a relationship model.
$ rails g model Relationship
Add following_id (following side id) and follower_id (following side id) etc. to the migration file.
202008111333110_create_relationships.rb
class CreateRelationships < ActiveRecord::Migration[5.2]
def change
create_table :relationships do |t|
#Follower
t.integer :following_id
#Followed side
t.integer :follower_id
t.timestamps null: false
end
add_index :relationships, :following_id
add_index :relationships, :follower_id
add_index :relationships, [:following_id, :follower_id], unique: true
end
end
Don't forget ...
$ rails db:migrate
From here ** ① Looking at the follower ** ** ② Looking at the side to be followed ** It is necessary to distinguish between the two. Be careful as you will not know what it is if you make it ambiguous!
First of all ... ** 1. Think of the Relationship model in two parts ** ・ Active_relationships (following side's eyes) ・ Passive_relationships (eyes of the follower)
user.rb
class User < ApplicationRecord
has_many :active_relationships, class_name: "Relationship", foreign_key: :following_id, dependent: :destroy
has_many :passive_relationships, class_name: "Relationship", foreign_key: :follower_id, dependent: :destroy
end
Since it is just an "assuming" that one Relationship model is given a name and divided into two models, it is necessary to describe in class_name that it is really a Relationship model.
Also, from the perspective of the follower, the follower (follower_id) is pulled based on the follower (following_id), so it is necessary to specify the primary_key (foreign key) as the following_id.
On the contrary, from the perspective of the follower, the follower (following_id) is pulled based on the follower (follower_id), so it is necessary to specify the primary_key (foreign key) as the follower_id.
** 2. Think of the User model in two parts ** ・ Following (Looking at the side to follow) ・ Follower (the line of sight of the follower)
relationship.rb
class Relationship < ApplicationRecord
belongs_to :following, class_name: "User"
belongs_to :follower, class_name: "User"
end
As with the Relationship model, it is just an "assuming" that one User model is given a name and divided into two models, so it is necessary to describe in class_name that it is really a User model.
1st line: ** Describe the Relationships model (active_relationships because it is the side to follow here) ** It has already been explained where the above Relationships model is divided into two.
Line 2: ** Gather people followed via active_relationship ** Gather people followed through active_relationships. To collect the people who are followed, you will refer to the "follower" model, so write source :: follower. Since this series of flow is named "followings", it is described as has_many: followings.
user.rb
has_many :active_relationships, class_name: "Relationship", foreign_key: :following_id
has_many :followings, through: :active_relationships, source: :follower
Line 1: ** First, describe the Relationships model (passive_relationships here) ** It has already been explained where the above Relationships model is divided into two.
2nd line: ** Gather people you follow via passive_relationship ** Gather people who are followed through passive_relationships. To collect the people who are followed, you will refer to the "following" model, so write source :: following. Since this series of flow is named "followers", it is described as has_many: followers.
user.rb
has_many :passive_relationships, class_name: "Relationship", foreign_key: :follower_id
has_many :followers, through: :passive_relationships, source: :following
So the final description in the User model is as follows.
user.rb
class User < ApplicationRecord
#The line of sight of the follower
has_many :active_relationships, class_name: "Relationship", foreign_key: :following_id
has_many :followings, through: :active_relationships, source: :follower
#Looking at the side to be followed
has_many :passive_relationships, class_name: "Relationship", foreign_key: :follower_id
has_many :followers, through: :passive_relationships, source: :following
end
This is the end.
In order to complete the follow function, it is necessary to implement view and controller separately.
That said, I actually experienced and felt that the mountain of follow function implementation lies in "understanding the description of the User model", so I think that if you cross this mountain, you can implement it without difficulty. : thumbsup:
I think the point this time is ** to think about one model in two **.
In the first place, the structure that both the follower and the follower refer to one model called the User model and bring the data is complicated, so it seems to be the relationship between the Post model of the like function and the User model. In addition, if you assume that the User model is two models (although it is actually one model) and organize the relationships, I think that you can think that it may be an unexpectedly simple story.
Thank you for reading this far. I'm a beginner who doesn't have enough knowledge yet, so I would appreciate it if you could give me some advice if there are any mistakes.
Recommended Posts