36日目 データベースのテーブル同士の関連付け対応②(外部キー追加)
こんにちは。昨日の記事の続きです。
今日は、データベースの最初の設計から、テーブル同士の関連付けが行えるようにテーブルに外部キーを含めるようにクラス図書き直し&ER図を作成しましたので、その図を基に、Railsを用いてデータベースへの反映を行ないます。
これまでの変更をローカルのGitリポジトリに登録しておく
データベースへの反映を行なおうと思いますが、その前に、これまでの変更(migrationファイルとmodelファイルの追加等)をGitリポジトリに登録しておきます。
なぜかというと、クラス図とER図を作成して、データベースの構成が変わってくるので、その変わる前の構成をGitリポジトリに残しておいたほうが、変更履歴として追っていけるため。
登録方法についてはわたしが以前に書いた以下の記事の「3. 変更内容をGitにコミット(登録)」が参考になると思います。
まず、コマンドプロンプトを立ち上げて、「cd」コマンドなどで自分が開発したRailsアプリケーションのプロジェクトデータがある場所(例:「C:\Users\youto\Desktop\playtool\real_chat」)まで作業場所(カレントディレクトリ)を移動させたあと、
git status
にてコマンドを入力します。

これまで、「Model(モデル)」追加のためにコマンドを入力して自動で追加されたmigrationファイルやmodelファイル等、赤字(コミットの追跡対象でない状態)で表示されていると思いますが、以下のコマンドですべて緑字(コミットの追跡対象とした状態)にします。
git add .
上記のコマンドを入力した後、「git status」コマンドを再度入力すると、

先ほどまで赤字だったファイル名が全て緑字に変わると思いますので、その状態で、以下のようにコミットします。("Add [Room], [User] and [Comment] models"の部分は適当に付けたコメントです。)
git commit -m "Add [Room], [User] and [Comment] models"
外部キー(カラム)追加用のmigrationファイル作成
これまでの変更をGitリポジトリに残しましたので、これからデータベースのテーブルへ外部キーを新しく追加しようと思います。
今回、外部キーの追加対象となるのは
・「User」モデルの部屋ID(「Room」モデルのIDから参照可能)
・「Comment」モデルのユーザーID(「User」モデルのIDから参照可能)
の2つのモデル(テーブル)です。
ここで、「User」モデルと「Comment」モデルは既にデータベースへ反映済(それぞれテーブルを作成済)ですので、既存のテーブルへ「外部キー(カラム)追加」という形で変更を行ないます。
既存のテーブルへ外部キーを追加する際にはmigrationファイルを作成しますが、そのmigrationファイルを自動作成するコマンドは以下の通りです。(以下は「User」モデルを対象としています。)
jruby -S bundle _1.17.3_ exec rails generate migration AddReferencesToUsers
また、「Comment」モデルに外部キーを追加するためのmigrationファイルを自動作成するコマンドは以下の通りです。
jruby -S bundle _1.17.3_ exec rails generate migration AddReferencesToComments
前者と後者のコマンドはほぼ同じで、違いはコマンドの最後が前者は「AddReferencesToUsers」で、後者は「AddReferencesToComments」となっており、太字部分が変わっています。それぞれ対象とするモデル名を複数形にした名前に合わせて、文字列を微妙に変えております。
それぞれコマンドプロンプトからコマンドを入力してみます。
「User」モデルの場合は、以下のようにコマンド入力することによって、「(YYYYMMDDhhmmss)_add_references_to_users.rb」という新しいmigrationファイルが作られます。※(YYYYMMDDhhmmss)は年月日

また、「Comment」モデルの場合も以下のようにコマンドを入力することで、「(YYYYMMDDhhmmss)_add_references_to_comments.rb」という新しいmigrationファイルが作られます。

試しにVisual Studio Codeを起動して、Railsアプリケーションのプロジェクトデータがある場所を開いてみます。
プロジェクトデータがある場所を開いたら、Visual Studio Codeの画面左側に「エクスプローラー」ビューが表示されているかと思いますが、そこで、「db」⇒「migrate」の順にクリックしてファイル等を展開してみてください。

上記のように、展開されたファイルの中に
「(YYYYMMDDhhmmss)_add_references_to_users.rb」
「(YYYYMMDDhhmmss)_add_references_to_comments.rb」
という2種のファイルがあることが確認できるかと思います。
作成したmigrationファイルにreferences型のカラムを追加(編集)
前述でVisual Studio Codeから新しく作成したmigrationファイルがあることを確認できたら、まずは「User」モデルを対象に外部キー制約のあるカラムを追加するようにmigrationファイルの中身を編集します。
そこで、Visual Studio Codeの「エクスプローラー」ビューの
「app」⇒「migrate」フォルダの中にある
「(YYYYMMDDhhmmss)_add_references_to_users.rb」をダブルクリックしてください。
ダブルクリックすると、Visual Studio Codeの画面右側が以下のように「(YYYYMMDDhhmmss)_add_references_to_users.rb」の中身が表示されているかと思います。

そこで以下のようにコードの中身を変更します。
変更前:
1 class AddReferencesToUsers < ActiveRecord::Migration
2 def change
3 end
4 end
変更後:(※3行目を追加挿入)
1 class AddReferencesToUsers < ActiveRecord::Migration
2 def change
3 add_reference :users, :room, foreign_key: true # 追加した行
4 end
5 end
上記のように、変更後は3行目が新しく追加されていますが、この追加された「add_reference :users, :room」の部分の意味は
『1つの「room(Room)」モデルから複数の「user(User)」モデルへと参照(reference)できるカラムを追加する』
ということです。(※「foreign_key: true」は外部キー制約というオプションを有効にする、という意味になります。)
続いて、「Comment」モデルも同様に外部キー制約のあるカラムを追加するようにmigrationファイルの中身を編集します。
「User」モデルの場合と同様に、Visual Studio Codeの「エクスプローラー」ビューの「app」⇒「migrate」フォルダの中にある
「(YYYYMMDDhhmmss)_add_references_to_comments.rb」をダブルクリックしてください。
すると、Visual Studio Codeの画面右側が以下のように「(YYYYMMDDhhmmss)_add_references_to_comments.rb」の中身が表示されているかと思います。

そこで以下のようにコードの中身を変更してください。
変更前:
1 class AddReferencesToComments < ActiveRecord::Migration
2 def change
3 end
4 end
変更後:(※3行目を追加挿入)
1 class AddReferencesToComments < ActiveRecord::Migration
2 def change
3 add_reference :comments, :user, foreign_key: true # 追加した行
4 end
5 end
上記のように、変更後は3行目が新しく追加されています。
追加された「add_reference :comments, :user」の部分の意味は
『1つの「user(User)」モデルから複数の「comment(Comment)」モデルへと参照(reference)できるカラムを追加する』
ということです。
作成・編集したmigrationファイルをデータベースへ反映
前章まででmigrationファイルの作成・編集を行なったら、Railsを用いて変更点をデータベースへ反映します。
データベースへの反映は以下のコマンドにて実施可能です。
jruby -S bundle _1.17.3_ exec rake db:migrate
実際にコマンドプロンプトから入力すると、以下のように表示されます。(追加された2つのmigrationファイルを反映するため、2回分のデータベースへの反映メッセージが表示されるような感じになると思います。)

ここで、前章までに開いたVisual Studio Codeの画面へと戻って、以下のように画面左側の「エクスプローラー」ビューから、「db」フォルダをクリックし、「schma.rb」ファイルをクリックしてみてください。

そしたら、「schma.rb」の中身が以下のように変更されていると思います。(図中の青い吹き出しが指す部分)

参考
おわりに
ここまで読んでくださって、ありがとうございました。
次回はモデル(テーブル)同士の関連付けが行えるようにアソシエーションの設定を行なう予定です。
次回に続きます。よろしくお願いいたします。