1対多のアソシエーション
2020.8.21
アソシエーション(Association)とは
関連を使えば、DB上の紐付けを前提にして、モデルクラス同士の紐付けを定義することができる。
これによって、オブジェクト指向に沿ったやり方で、関連するデータにアクセスすることが可能になる。
アソシエーションは紐付けの際に必ず定義しなければならないわけでも、必ずセット(has_oneとbelong_toなど)で定義しなければならないわけでもない。
ユーザーが複数のタスクを抱えている場合を考える
いわゆる1対多の関係
User
が複数の Task
を持っているので(User has many tasks)、
class User < ApplicationRecord
has_many: tasks # Task の複数形
end
Task
は一つの User
に属しているので(Task belongs to a User)、
class Task < ApplicationRecord
belongs_to: user # User の単数形
end
たったこれだけで、Railsは「 Task
は、 user_id
を外部キーとして抱えている」ということを認識してくれる。(※外部キーは モデル名_id
とする必要あり)
アソシエーションしたデータの受け取り方
「ユーザーが持っているタスク」を取得
@user.tasks
→複数のタスクが格納された配列が返る
「このタスクを持っているユーザー」を取得
@task.user
→ユーザーが返る
アソシエーションを使用しない場合との比較
新規作成処理では...
アソシエーションを使用しない場合
@task = Task.create(text: "本を返す", user_id: @user.id)
アソシエーションを使用する場合
@task = @user.tasks.create(text: "本を返す")
取得処理では...
アソシエーションを使用しない場合
@user = User.find(1)
@task = Task.where(user_id: @user.id) # いちいち外部キーを指定
アソシエーションを使用する場合
@user = User.find(1)
@tasks = @user.tasks
このように、アソシエーションを使用すると外部キーの指定が不要になり、直感的な記述ができる。
削除処理では...
アソシエーションを使用しない場合
@tasks = Task.where(user_id: @user.id)
@tasks.each do |task|
task.destroy
end
@user.destroy
アソシエーションを使用する場合
@user.destroy
この記述だけで、Railsが@userに関連する全タスクをまとめて削除してくれる