やること
今回は、アノテーション付きのモデル作成とテーブル作成までを行いたいと思います。
やることは以下の通り
- GEM(annotate)の追加
- ジェネレータコマンドでモデル作成
- マイグレーションコマンドでテーブル作成
- シードで初期レコード追加
GEM(annotate)の追加
annotateというGEMを追加してマイグレートされる度に自動的にモデルにテーブル構造がアノテーションとして付与されるよう設定を行おうと思います。
まずは、Gemfileにannotateを追加します。
group :development, :test do
# 〜関係ないとこは省略
gem 'annotate'
end
今回は開発環境(development)とテスト環境(test)へのみインストールするため、
group :development, :test doの中に記載します。
あとはdocker-compose build
すればGemインストール完了
次にマイグレートする度に自動でテーブル構造を書き出すよう以下のコマンドを実行します。
docker-compose run web rails g annotate:install
コンテナでコマンド実行する際に
docker-compose run 〜
とdocker-compose exec 〜
の
2通りの方法がありますが、調べてみると・・・
run:コンテナ起動してコマンド実行
exec:起動中のコンテナでコマンド実行
の違いがあるそうです。
試しにコンテナを起動していない状態でexecしたら以下のエラーになりました。
コンテナが見つかりませんとのこと。
ERROR: No container found for web_1
ジェネレータコマンドでモデル作成
ジェネレーターコマンドを実行してモデルファイルを作成しようと思います。
実行コマンドはこんな感じ(コンテナ起動済みなのでexecで!)
docker-compose exec web rails g model bike name:string
rails g model 'テーブル名' 'カラム名:型' 'カラム名:型'・・・
で
モデルファイルとマイグレーションファイルが作成されます。
今回は文字列型のnameというカラムを持ったbikeテーブルを作成します。
ちなみにidはPKとして自動作成されるのでカラムとしての指定は不要です。
マイグレーションファイル内のCREATE文ではテーブル名が複数形(〜s)の形で作成されるので、実際のテーブルはbikesという名前になります。
次にsrc/app/models/下にモデルファイルが作成されているので、中身を確認してみます。
class Bike < ApplicationRecord
end
この時点ではアノテーションの付与はまだ行われていません。
src/db/migrate下にマイグレーションファイルが作成されたので、こちらも中身を確認してきます。
class CreateBikes < ActiveRecord::Migration[5.2]
def change
create_table :bikes do |t|
t.string :name
t.timestamps
end
end
end
テーブル作成用のCREATE文が作成されていることがわかります。
t.timestampsはテーブルへ作成日と更新日のカラムを追加してくれるので、このままにしておきます。
あとsrc/test配下にテスト用のファイルが出力されていましたが、これはおいおい勉強していこうと思います。。今回は割愛。
マイグレーションコマンドでテーブル作成
docker-compose exec web rake db:migrate
を実行し、テーブル登録を行います。
実行後にモデルファイルの中身を再度確認してみます。
# == Schema Information
#
# Table name: bikes
#
# id :bigint(8) not null, primary key
# name :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
class Bike < ApplicationRecord
end
するとアノテーションが付与されていることがわかります。
次に以下のコマンドを実行してMySQLへ接続してテーブルが登録されているかを確認します。
docker-compose exec db mysql -u root -p
実行後、パスワードを入力してMySQLへ接続
ここからはMySQLのコマンドでの操作になります。
use app_development;
で使用するデータベースを選択
マイグレートするとデフォルトでxxxxx_developmentのデータベースに登録されるようです。
show tables;
でbikesテーブルが正しく登録されていることがわかります。
+---------------------------+
| Tables_in_app_development |
+---------------------------+
| ar_internal_metadata |
| bikes |
| schema_migrations |
+---------------------------+
3 rows in set (0.00 sec)
DESC bikes;
で定義情報が先ほどアノテーションとして付与されていたものと同じであることが確認できます。
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
docker-compose exec web rake db:migrate
は、実行していないマイグレーションファイルを実行してくれるため、この状態で再度実行すると以下のように変更する内容がないと言われます。
Model files unchanged.
試しにdocker-compose exec web rake db:rollback
で直前の動作(bikesテーブルの追加)を取り消すと再びmigrateができることが確認できました。
シードで初期レコード追加
シードと呼ばれる初期データ投入用の機能を利用してbikesテーブルにレコード追加してみようと思います。
src/db/seeds.rbに以下を追加します。
# bikesテーブルにレコード追加
Bike.create(
[{ name: 'CB250F'},
{ name: 'AX-1'},
{ name: 'CB350'},
{ name: 'FMX650'},
{ name: 'CB1000R'}]
)
BikeモデルがApplicationRecordクラスを継承し、
ApplicationRecordクラスがO/Rマッパーの機能を備えたActiveRecordクラスを継承しているため、これだけでテーブルへレコード追加ができます。
あとはdocker-compose exec web rake db:seed
を実行するだけ
テーブルの中身を確認すると
+----+---------+---------------------+---------------------+
| id | name | created_at | updated_at |
+----+---------+---------------------+---------------------+
| 1 | CB250F | 2018-09-24 06:11:19 | 2018-09-24 06:11:19 |
| 2 | AX-1 | 2018-09-24 06:11:19 | 2018-09-24 06:11:19 |
| 3 | CB350 | 2018-09-24 06:11:19 | 2018-09-24 06:11:19 |
| 4 | FMX650 | 2018-09-24 06:11:19 | 2018-09-24 06:11:19 |
| 5 | CB1000R | 2018-09-24 06:11:19 | 2018-09-24 06:11:19 |
+----+---------+---------------------+---------------------+
5 rows in set (0.01 sec)
レコード登録が行われていることが確認できます!
HONDAの車種ばっか笑
今日はここまで!
次の記事でテーブル同士の関連付けについてまとめていこうと思います。