こんにちは。
早く駆け出したい修行僧です。
勉強用アプリにてカラムを追加する方法を
学んだので、アウトプットしていきます。
尚、「それは違うよ」など訂正箇所がございましたら、
愛のあるご指摘を頂けたら幸いです。
環境
MacBook Air(M1,2020) Monterey 12.2.1
Ruby 3.1.0
Rails 6.1.4.6
PostgreSQL 14.2
何をしたいか?
まずは、foods
テーブルにstring
型のimage
カラムを追加したい。
現状のテーブルとカラム
追加前のfoods
テーブルとカラムは以下の通りです。
Column | Type | Collation | Nullable |
------------+--------------------------------+-----------+----------+--
id | bigint | | not null |
user_id | bigint | | not null |
name | character varying | | not null |
comment | text | | |
created_at | timestamp(6) without time zone | | not null |
updated_at | timestamp(6) without time zone | | not null |
カラムを追加する
カラムを追加する前に注意点があります。
それは 既存のマイグレーションファイルを直接編集しないことです。
既存のマイグレーションファイルを編集してrails db:migrate
としても何も変更が加えられません。なぜなら、Railsは既にマイグレーションを実施したと認識しているからです。
以下、Railsガイドにて記載があります。
一般に、既存のマイグレーションを直接変更するのはよくありません。既存のマイグレーションを変更すると、自分自身はもちろん、共同作業者も余分な作業を強いられます。さらに、既存のマイグレーションがproduction環境で実行中の場合、ひどい頭痛の種になるでしょう。既存のマイグレーションを直接修正するのではなく、修正用のマイグレーションを新たに作成してそれを実行するのが正しい方法です。これまでコミットされてない(より一般的に言えば、これまでdevelopment環境以外にデプロイされたことのない)マイグレーションを新たに生成し、それを編集するのが害の少ない方法です。
Railsガイド
では、どうしたら良いのでしょうか。
ジェネレータでマイグレーションを新たに作成すれば良いですね。
以下のコマンドを実行します。(今回はfoods
テーブルにstring
型のimage
カラムを追加)
$ rails g migration AddImageToFoods image:string
#=> rails g migration Addカラム名Toテーブル名 カラム名:データ型
実行すると以下のファイルが作成されます。
Running via Spring preloader in process 3701
invoke active_record
create db/migrate/生年月日_add_image_to_foods.rb
カラム追加後の状態
では、実際のファイルの中身はどうなっているでしょうか。
まずは新しく作成されたマイグレーションファイルを見ていきましょう。
class AddImageToFoods < ActiveRecord::Migration[6.1]
def change
add_column :foods, :image, :string
end
end
こうですね。しっかりとfoods
テーブルにimage
カラムが追加されていることがわかります。
NOTNULL
制約などのバリデーションを追加する必要があれば実施してしまいましょう。今回は追加する予定はないので省略します。
マイグレーションの実施
ファイルの確認と各種編集が終わったらマイグレーションを実施しましょう。
以下のような表示がされていれば成功です。
$ rails db:migrate
== 20220307002415 AddImageToFoods: migrating ==================================
-- add_column(:foods, :image, :string)
-> 0.0108s
== 20220307002415 AddImageToFoods: migrated (0.0109s) =========================
では、スキーマを見ていきましょう。
create_table "foods", force: :cascade do |t|
t.bigint "user_id", null: false
t.string "name", null: false
t.text "comment"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
+ t.string "image"
t.index ["user_id"], name: "index_foods_on_user_id"
end
こうですね。スキーマでimage
カラムが追加されています。
最後にターミナルでもテーブルの状態がどうなっているか見てみましょう。
Column | Type | Collation | Nullable |
------------+--------------------------------+-----------+----------+--
id | bigint | | not null |
user_id | bigint | | not null |
name | character varying | | not null |
comment | text | | |
created_at | timestamp(6) without time zone | | not null |
updated_at | timestamp(6) without time zone | | not null |
image | character varying | | |
先ほどまでは、updated_at
までしかありませんでしたが、image
カラムが追加されていることがわかりますね。
お疲れ様です!
最後までお読みいただきありがとうございました。
参考
Railsガイド
Ruby on Rails カラムの追加と削除 - @azusanakano さん
Railsでデータベースカラムの追加を行う方法 - @ryosuketter さん