いつも忘れてしまう、Railsマイグレーションコマンド
Ruby on Railsでテーブル・モデルを新規作成する際に、作成コマンドを必ず忘れてその度に調べています・・。
なので今回は作業に伴って手順を残しておこうと思います。
私と同じような人のためになりますように・・。
実行環境
・Rails 5.1.7
・ruby 2.5.8p224
大雑把な実行手順
・マイグレーションファイルを作成する
・マイグレーションを実行する
・モデルを作成する(テーブル新規追加のみ)
(テーブルを新規作成する場合はモデルを作成するとマイグレーションファイルも作成される)
・アソシエーション(テーブル同士の関連付けが必要な場合)
マイグレーションファイルを作成する
- マイグレーションファイルを生成する
- 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にならない為アソシエーション定義は効いているようです。
今日はここまで!では、また〜。
ディスカッション
コメント一覧
まだ、コメントがありません