8
13

More than 3 years have passed since last update.

【Rails】モデルの関連付けを行う

Last updated at Posted at 2019-11-27

関連付けとは

Railsでは、モデルやテーブル同士の関係を設定することができます。
例えばUserモデルとTaskモデルの関係などを定義します。
(この場合、1人のユーザーが複数のタスクを持っている)

何がうれしいのか

必要な記述が少なく、シンプルになります。
TODOアプリを例に説明すると、以下のように記述が簡素化します。

タスク作成時

Task.create(title: "パンを買う", user_id: @user.id)

@user.tasks.create(title: "パンを買う")

ユーザー削除時

@tasks = Task.where(user_id: @user.id)
@tasks.each do |task|
  task.destroy
end
@user.destroy

@user.destroy

その他、以下のようなメソッドが使えるようになります。

メソッド 用途
task.user タスクに紐付いたUserオブジェクトを返す
user.tasks Userのタスクの集合を返す
user.tasks.build(arg) userに紐付いた新しいTaskオブジェクトを返す
user.tasks.find_by(id: 1) userに紐付いていて、idが1であるタスクを検索する

実装してみる

簡単なTODOアプリを例に、UserモデルとTaskモデルの関連付けをします。
Ruby on Railsで簡単なアプリを作成
【Rails】ログイン機能を実装する

tasksテーブルにuser_idを追加

$ rails g migration Addカラム名Toテーブル名 カラム名:データ型でカラムを追加するマイグレーションファイルを作成できます。

$ rails g migration AddUserToTasks user:references

作成されるファイル

[timestamp]add_user_to_tasks.rb
class AddUserToTasks < ActiveRecord::Migration[5.1]
  def change
    add_reference :tasks, :user, foreign_key: true
  end
end

ここでは外部キー制約を持ったreference型user_idというカラムを追加し、user_idにはusersテーブルのidカラムに入っているデータだけを許可します。
(データベース上には、usersテーブルのidカラムの型であるinteger型として登録されます。)
外部キー (foreign key)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

$ rails db:migrate

has_manybelongs_toで関連付け

Taskモデルにbelongs_to、Userモデルにhas_manyを記述し、関連付けを行います。
その他default_scopeで取り出す時の順番を指定したり、dependent: :destroyでユーザーが削除された時にそのユーザーの持つタスクを全て削除するように設定できます。

/app/model/task.rb
class Task < ApplicationRecord
  belongs_to :user
.
.
end
/app/model/user.rb
class User < ApplicationRecord
  has_many :tasks, dependent: :destroy
.
.
end

タスク登録処理を修正

これまでTask.newで取得していたタスクオブジェクトをcurrent_user.tasks.buildで書き換えます。
(このアプリではcurrent_userという関数で現在ログイン中のユーザーオブジェクトを返すことができます。)

.
.
def create
    # @task = Task.new(task_params)
    @task = current_user.tasks.build(task_params)
    if @task.save
      flash[:success] = "タスクを追加しました。"
.
.

まだこのアプリにはユーザー削除の機能がないので、削除時の動作の実装は割愛しますが、@user.destroyでユーザーに紐づいた全てのタスクを削除できます。

外部キーを設定したカラムにnullを許可したい

optional: trueを指定すると、nullを許可できます。

app/model/task.rb
belongs_to :user, optional: true

その他

外部キーを含むテーブルを作成する際には
$ rail g model user:references ...
$ rail g migration user:references ...
などで作ることが出来ます。

モデルを作った場合には、デフォルトでbelongs_to :userが付与されます。

参考

Active Record の関連付け - Rails ガイド
外部キーにnullが入ることを許容する[Rails]

8
13
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
8
13