いつも忘れてしまう、Railsマイグレーションコマンド

2021年5月8日

Ruby on Railsでテーブル・モデルを新規作成する際に、作成コマンドを必ず忘れてその度に調べています・・。

なので今回は作業に伴って手順を残しておこうと思います。
私と同じような人のためになりますように・・。

実行環境
・Rails 5.1.7
・ruby 2.5.8p224

大雑把な実行手順
・マイグレーションファイルを作成する
・マイグレーションを実行する
・モデルを作成する(テーブル新規追加のみ)
(テーブルを新規作成する場合はモデルを作成するとマイグレーションファイルも作成される)
・アソシエーション(テーブル同士の関連付けが必要な場合)

マイグレーションファイルを作成する

  1. マイグレーションファイルを生成する
  2. upメソッドとdownメソッドを定義する(必要な場合のみ)
マイグレーションファイル生成コマンド
rails g migration マイグレーションファイル名 [カラム名:型] [オプション]

例 rails g migration create_user user_name:string
   rails g migration add_group_code_to_organization group_code:string

※[]で囲まれた部分は省略可能

upメソッドとdownメソッドを定義する

Railsガイドによると、特定のマイグレーション定義のみ使用する場合は、マイグレーションファイルにchangeメソッドが定義されていれば、ロールバックする事ができます。

しかし、それ以外のマイグレーション定義を使用したい場合は、生成されたマイグレーションファイルにupメソッドとdownメソッドを定義してロールバックを可能としておく必要があります。

例
class AddGroupCodeToOrganization < ActiveRecord::Migration[5.1]
  def up
    add_column :organizations, :group_code, :string
  end

  def down
    remove_column :organizations, :group_code, :string
  end
end


class CreateNonces < ActiveRecord::Migration[5.1]
  def change
    create_table :nonces do |t|
      t.string :nonce
    end
  end
end

マイグレーションを実行する

マイグレーションを実行する事でテーブルに対して変更が行われます。
コマンドは以下です。

rails db:migrate

モデルを作成する(テーブル新規追加)

テーブルを新規追加する場合、以下のコマンドでマイグレーションファイルとモデルを一括で生成できます。

rails g model モデル名 [カラム名:型] [オプション]

例)
rails g model User name:string phone:integer

また、既にマイグレーションファイルが存在しており、モデルを後から生成したい場合はオプションに「-s(スキップ)」を設定します。

rails g model モデル名 [カラム名:型] -s

※既に存在するファイルのみ、生成をスキップ

また、アソシエーション定義をする場合はモデルの生成時に外部キーを作っておきます。

rails g model モデル名 関連するテーブル名:references [カラム名:型] [オプション]

生成されたマイグレーションファイルに必ず外部キー制約を付けます。

例)
class AddUserIdToNonces < ActiveRecord::Migration[5.1]
  def change
    add_reference :nonces, :user, foreign_key: true
  end
end

アソシエーション(テーブル関連付け)

テーブルの関連付けを行う場合は、先述の外部キー定義の後にモデルを編集します。

まず従属テーブル(外部キーを定義したテーブル)のモデルに対して「belongs
_to」関連付けを定義します。

# 従属テーブルに対するアソシエーション定義例
class Nonce < ApplicationRecord
    belongs_to :user
end

次に主テーブルのモデルに対して「has_one」関連付けを定義します。

# 主テーブルに対するアソシエーション定義例
class User < ApplicationRecord
    has_one :nonce
    has_secure_password
end

Railsコンソールで確認してみる

最後にアソシエーション定義が効いているか、Railsコンソールで確認してみます。

予め主テーブルにレコードを作成しておいて、従属テーブルを参照してみます。

[10] pry(main)> User.first.nonce
  User Load (1.0ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
  Nonce Load (0.7ms)  SELECT  "nonces".* FROM "nonces" WHERE "nonces"."user_id" = $1 LIMIT $2  [["user_id", 1], ["LIMIT", 1]]
=> nil

従属テーブルにはレコードが1件もないので結果はnilが返却されましたが、NoMethodErrorにならない為アソシエーション定義は効いているようです。

今日はここまで!では、また〜。