LoginSignup
1
0

More than 5 years have passed since last update.

テーブル間の依存関係について、名前から推測してくれるのはありがたいけれど、どこまでやってくれているのか

Last updated at Posted at 2018-11-16

目的・前提

Ruby on Railsではテーブル作成に使うマイグレーションファイルにテーブルの依存関係を数行追加するだけで
簡単に依存関係が構築できます。しかし、僕はいつもチュートリアルを読むとき、「どこまでがRuby on Railsで推測してくれるのか」についてわからなくります。
今回は、マイグレーションファイルで使用する.references型についてまた不明点がでてきましたので、現時点で調べた結果を記載します。

Railsチュートリアル「13.1.1 基本的なモデル」より
https://railstutorial.jp/chapters/user_microposts?version=5.1#sec-the_basic_model
内容としては、
・テーブル「Users」で管理されているユーザが、ツイッターのようなテキストを投稿する。
・テーブル「Microposts」でユーザが投稿したテキストを管理する。
なのですが、Micropostsで管理されるテキストがどのユーザが投稿したものなのかを管理吸うために2つのテーブルを紐付ける必要があります。
そのために、「Microposts」にあるカラム「user_id」は「Users」テーブルの「id 」カラムと紐付けることにします。という処理が必要になります。

下記2テーブルの関係について記載します。
#図1, 図2はいずれもRuby on Rails チュートリアル: 実例を使って Rails を学ぼうより引っ張ってきています。

image.png
図1.Usersテーブル

image.png
図2.Micropostsテーブル

コード

Userモデル.rb
class User < ApplicationRecord
  has_many :microposts, dependent: :destroy
  #micropostモデルに依存されています、という記載
  #userモデルのレコードを削除したらそれに紐付いたmicropostモデルの記事も削除される
end
Micropostモデル.rb
class Micropost < ApplicationRecord
  belongs_to :user
  #userモデルに依存します、という記載
end
マイグレーションファイル.rb
class CreateMicroposts < ActiveRecord::Migration[5.1]
  def change
    create_table :microposts do |t|
      t.text :content
      t.references :user, foreign_key: true
      #userモデルに外部制約キーを付ける

      t.timestamps
    end
    add_index :microposts, [:user_id, :created_at]
    #user_idにindexを付ける
  end
end

Micropostモデルに記載のbelongs_to :userについて

belongs_to関連付けを行なうと、他方のモデルとの間に「1対1」のつながりが設定されます。
"belongs_to :user"と記載すれば、Usersモデルのテーブル「Users」でデフォルトで必ず作成される「id」に依存する、とRailsで判断されます。
依存するとは、例えば、テーブル「Users」の「id」が「10」であるユーザが削除されると、そのユーザが投稿したテキストも自動的に削除される、ということです。
この関連付けのためにはUserモデルの方でも記載が必要です。
それが"has_many :microposts"です。

Userモデルに記載の"has_many :microposts"について

has_many関連付けが使用されている場合、そのモデルのインスタンスは、反対側のモデルの「0個以上の」インスタンスを所有します。
「2.3 has_many関連付け」より

この場合の"反対側"とは"belongs_to :user"を記載したMicropostモデルを指します。つまり
・belongs_to :user : Userモデルに依存します。
・has_many :microposts : たくさんのMicropostモデルを所有します。
という親「Userモデル」、子「Micropostモデル」の関係がこれで築かれます。

"dependent: :destroy"によって、もしUsersテーブルにあるユーザが削除されたとき、そのユーザが作成したMicropostの記事は連動して削除されます。

t.references :user, foreign_key: trueについて

".references"を記載すると”指定したモデル名_id”のカラムが追加されます。
この場合":user"と記載しているので、カラム"user_id"が追加されます。
同時にuser_idにはindexが付与されます。なので単にindexを付与するための下記の記載は不要となります。

index: true

"foreign_key: true"を記載すると指定したモデル名_idに外部キー制約を付与します。つまりこのuser_idからむはモデル「User」で作成されたテーブル「Users」のデフォルトで必ず作られる「id」を参照して紐づけます。

残った課題

上記でUserモデルとMicropostモデルの依存関係の構築は完了しましたが、.referencesで指定した際に自動的にindexが付与されのであれば

add_index :microposts, [:user_id, :created_at]

の行がいらないはずです。これはRailsチュートリアルの後の章で説明される複合キーインデックスを扱うために必要とのことです。
それについて、覚えていたら後から記載しようと思います。

1
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
1
0