LoginSignup
0
0

【Rails】アソシエーションを理解するための基礎知識①

Last updated at Posted at 2024-02-03

こんにちは!
今回はフォロー、フォロワー機能を作っているときに初心者がそもそもこの用語どういう意味だっけ?となってしまう部分や、この機能ってなんで必要なんだろうと思う部分をまとめてみました!
フォロー、フォロワー機能以外にもアソシエーションはいろんなところで使うので是非参考にしてください:ok_hand_tone1:

FK(Foreign_key)とPK(Primary_key)とは

()の中に書いてあるのはヒントです!というか答えです。でも初心者は省略された瞬間分からなくなりますよね:innocent:でもとても重要なのでここで覚えてしまいましょう!!
順番は逆になってしまいますが、まずPK(Primary key)とは何か説明します。

PK(primary key)とは

PKは親のidとよく表現されますが、すなわち、各モデルで割り振られるid部分に相当します。
ユーザーだと下のテーブルのidの部分にあたります。
よく言われるユーザーidのことですね。ユーザー以外でもほとんどのモデルにPKは必要です。投稿機能を実装するなら投稿自体のid、コメントならコメント自体のidが必要になってきます。
なぜかというと、PKがないとユーザーや投稿などを消したいと思っても、idがないと何の情報をもとに消すかと考えたとき、名前をもとに消していたら全く同じ名前の人や投稿の内容も消えてしまいますよね?そんなことが起きないようにidがあることで、idと一緒に保存している情報ごと消したいときとても便利になります!
ちなみにすべてのモデルに自動的にidのカラムは作成されるので、ご心配なく!(created_at,updated_atも勝手に作成されます。)

id(PK) name introduction
1 ハム太郎 とっとこ走るよ
2 金太郎 熊あぶない!
3 銀太郎 私のハムスター
4 桃太郎 桃から生まれました

FK(Foreign key)とは

次にFKとは何でしょうか。
FK(foreign key)とは、先ほど解説したPKをどこか他のモデルにも保存したいときに、他のテーブルにはFKという形で作成します。

どういうことかというと、例えば投稿のモデルを作成するとき、PK(投稿モデルでいう投稿のid)が作成されますよね。でもそれって誰の投稿?となったときに混乱が起きてしまいます。ここでFK(投稿モデルにおけるユーザーid)を作成しておくと、FKの情報をもとにユーザーの情報を探すことができます。
今の説明をテーブルで表すとこんな感じです。

id(PK) user_id(FK) title body
1 2 クマと一緒に鬼退治 今日の鬼は柱と一緒に退治した!
2 4 草刈り おじいさんと一緒に今日は草刈りday♪
3 1 ハムハム ヒマワリの種くれ!!!

1つ前のユーザーモデルのPK(userのid)と投稿モデルのFK(user_id)を見比べて、誰が投稿した内容か探してみてください!探せましたか?これがFKの便利なところです!

activeとpassive

フォロー、フォロワー機能の実装をしているときに、この辺りの理解が足りておらず脳死でコードを書いてしまっている人いませんか?(私です:sweat_smile:)今回はactiveとpassive以外にもその周辺で重要となってくるコードの説明もしちゃいます!まずは使用例を見てみましょう。

user.rb
has_many :active_relationships, class_name: "Relationship", foreign_key: :following_id
has_many :followings, through: :active_relationships, source: :follower
has_many :passive_relationships, class_name: "Relationship", foreign_key: :follower_id
has_many :followers, through: :passive_relationships, source: :following

active_relationshipsとは、例えると自分がログインしているアカウントで他の人をフォローするという、自発的な関係を作る=フォローすることを表しています。英語でもactiveは『活発な』という意味なので、そう考えると分かりやすいですね。
逆に3行目のpassive_relationshipsとは、自分がフォローされる立場の時、言い換えると受動的な関係=自分がフォローされること(他人が自分をフォロー)を示しています。
それにhas_manyがついているので、ユーザーはactive_relationships(自発的な関係=フォロー)とpassive_relationships(受動的な関係=フォロワー)をたくさん持っているという意味になります。

ではそのあとのclass_name: "Relationship"はなぜ必要なのでしょうか。それは、フォロー、フォロワー機能を実装する際にRelationshipというモデルを作成しており、そこでユーザーモデルのフォローした側のPK(フォローしたユーザーid)とフォロワー側のPK(フォロワーのユーザーid)を記録する役割をしている、すなわちRelationshipモデルはFKを2つもっていることになります。

しかし、アソシエーションを結ぶ上では先程説明したactive_relationshipsとpassive_relationshipsといったあだ名のような書き分けが必要となるため、ただhas_many :relationshipsと書いてしまうとフォロワー側の管理ができません。その上で、あだ名であるactive_relationshipsとpassive_relationshipsの出どころはどこ?正式なモデル名は?となったとき、class_name: "Relationship"と正しいモデル名を書くことで認識されるようになります。

ここまでくると分かってきたでしょうか。そうです!
foreign_keyの後ろに、フォローしている側のユーザーのFK(following_id)とフォロワー側のユーザーのFK(follower_id)とかき分けることで、active_relationshipsとpassive_relationshipsのどちらに各FKが関連しているか書く必要がありますね。

次に2行目と4行目の説明をします。
これはユーザー視点からみると、フォローする(following)人もたくさんいれば、フォロワー(followers)もたくさんいるのでどちらも必要な記述になります。
補足:先ほどのrelationshipはあくまでも関係性で、ユーザー自体のことは示していません。

そのあとのthrough: :active(passive)_relationshipsですが、フォローした人とフォロワーどうし何を通じて繋がっているのかという記述になります。フォローする人はactive_relationshipsを通じていますし、自分のフォロワーはpassive_relationshipsを通じているため、そのような記述となっています。
これを書かなければただのユーザーモデル同士の繋がりで終わってしまうので、Relationshipモデルに情報を格納できません。

あともう少しで完全理解できます!がんばれ!
最後にsourceは、難しく言うと参照元のモデルを示しています。どういうことかというと、followings側からすると、関係を作りたい対照はfollowerになりますよね。逆にfollower側からすると関係を作りたい対照はfollowing(自分)となりますね。私はこういった理解で覚えました。(間違っていたら修正依頼ください!お願いします:bow_tone1:

これで以上になります。図があった方が分かりやすいと思うのでそのうち付け足す予定ですが、私はこのレベルをうまくまとめる力がないため、参考にしたリンクを貼ります。非常に分かりやすい図がたくさん載せてありますし、アプリ作成をしながら勉強できる記事です!あ、このアプリを作って序盤でエラーが出たら私のブログを遡ってみてください笑 私がつまずいたところがまとまっています。もしかしたら同じところでつまずいているかも?

あくまでも初心者からの初心者に向けた記事なので、もうわかってるよーという方はここまで見ていないと思いますが、見てくださった方今日もお疲れさまでした!では!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0