Rails Model migration - izudon/izudon.github.io GitHub Wiki
- マイグレーションの実行(最後まで実行)
$ rails db:migrate
- マイグレーションを1つ戻す
$ rails db:rollback
- マイグレーションをいくつか戻す
$ rails db:rollback STEP=<N>
- マイグレーションがどこまで実行されたかを確認
$ rails db:version
- マイグレーションをあるバージョンまで進ませる。
$ rails db:migrate VERSION=<version>
- マイグレーションを3つ戻し再度3つ実行する
$ rails db:migrate:redo STEP=3
- あ
$ rails db:migrate:status
- マイグレーションファイルは
rails g migration
コマンドで生成できるが、 最終的には手作業目視確認にて完成させなければならない。 - マイグレーションファイル名、クラス名、マイグレーションの内容には、
関連性があり、
ある種の規則をが守られていなければエラーとなってマイグレーションできない。 - 参考資料:
Active Record マイグレーション - Railsガイド
- マイグレーションファイルの作成。
$ rails g migration <マイグレーションクラス名> [[カラム1] [カラム2]...]
- マイグレーションファイルの作成取消。
$ rails d migration <マイグレーションクラス名>
- カラム追加のマイグレーションファイル作成
$ rails g migration AddPriceToSomethings price:integer
-
add_column
を呼び出すchange
メソッドが定義されている。
-
- カラム削除のマイグレーションファイル作成
$ rails g migration RemovePriceFromSomethings price:integer
-
remove_column
を呼び出すchange
メソッドが定義されている。
-
- マイグレーション クラス名 は パスカルケース(PascalCase) 。
- マイグレーション ファイル名 は スネークケース(snake_case) 。
-
テーブル名 や カラム名 は スネークケース(snake_case) 。
- キャメルケース(camelCase)
- パスカルケース(PascalCase)
- スネークケース(snake_case)
- ケバブケース(kebab-case)
- テーブル
- 作成
CreateTttt
- 削除
DropTttt
- 作成
- カラム
- 追加
AddCcccToTttt
- 削除
RemoveCcccFromTttt
- 追加
title:string content:text user:references
- Rails の認識ではDBは以下のようなオブジェクトからなり、
それぞれadd
したりremove
したり、change
したりするものである。
- テーブル系
-
create_
drop_
rename_
change_
table
-
create_
drop_
join_table
-
- カラム系
-
add_
remove_
rename_
change_
column
-
add_
remove_
reference
(他テーブルへの参照(≒外部キー列)) -
add_
remove_
timestamps
(作成日時と更新日時)
-
- 制約系
-
add_
remove_
rename_
index
(インデックス(一意性制約も含む)) -
add_
remove_
foreign_key
(外部キー制約) -
add_
remove_
check_constraint
(バリデーション)
-
- 属性系
-
change_
column_comment
(カラムへのコメント) -
change_
column_default
(カラムのデフォルト値) -
change_
column_null
(カラムの非ヌル制約) -
change_
table_comment
(レーブルへのコメント)
-
- ActiveRecord::ConnectionAdapters::SchemaStatements
- ActiveRecord::ConnectionAdapters::TableDefinition
- ActiveRecord::ConnectionAdapters::Table
create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options)
- 何も指定しなければ
* オートインクリメントされる
* 整数型のカラムが
*id
という名称で
* 勝手に 作成される。
create_table :user do |t|
t.string :email
t.timestamps
end
-
create_table
のid:
オプションに、
カラム名を指定すれば変えられる。
create_table :user, id: :member_no do |t|
t.string :email
t.timestamps
end
-
create_table
のid:
オプションに、
型を指定すれば変えられる。-
:string
など、整数型以外を指定した場合には、
オートインクリメントの指定も外れる。 -
:bigint
など、integer
以外でも整数型を指定した場合には、
オートインクリメントの指定は継続される。
-
create_table :user, id: :string do |t|
t.string :email
t.timestamps
end
-
create_table
のオプションでは対応不可能になってくるので、
id:
オプションにはfalse
と指定し、
列として明示的に定義しprimary_key: true
オプションをつける。
create_table :user, id: false do |t|
t.string :id, limit: 10, primary_key: true
t.string :email
t.timestamps
end
-
create_table
のprimary_key
オプションに、
カラム名を配列で指定する。-
primary_key: true
を複数カラムに指定するとエラーとなる。 - Rails は複合主キーに対応していないという噂があったが、
公式ドキュメント に堂々と乗っているのを先日発見した。
("Composit Primary Key"(複合主キー)の節)
-
- 但し実行時にこんなワーニングが出るので、
「非ヌル制約」+「(複合での)一意性制約」を併せて指定しておくと無難だと思う。WARNING: Active Record does not support composite primary key. authorizations has composite primary key. Composite primary key is ignored.
create_table :user, id: [:office_code, :desk_no] do |t|
t.string :office_code, limit: 10
t.integer :desk_no
t.string :email
t.timestamps
end
add_index :user, [:office_code, :desk_no], unique: true
add_column(table_name, column_name, type, **options)
カラムを追加する(一般的な列に適した列追加メソッド)。
create_table
の t.xxxxx
の正体はこれ。
-
t.column
はまさにこれ。 -
t.integer
などは、
t.column type: :integer
t.column :integer
などの略記。
(第1引数であるから最初に指定するなら引数名を省ける)
-
type:
型を指定 -
primary_key:
(単列での)主キー指定- 2つ以上のカラム =>
create_table
メソッドのprimary_key
オプションを使う(既述)。
- 2つ以上のカラム =>
-
index:
(単列での)インデックス要否- 2つ以上のカラム =>
add_index
メソッドを使う。 -
true
またはadd_index
メソッドのオプションをそのまま指定する。 -
index: { unique: true }
で「(単列での)一意性制約」となる。
- 2つ以上のカラム =>
-
limit:
長さの制約(文字列長やバイト長) -
null:
非ヌル制約(false
でヌル不可) -
default:
デフォルト値の指定
外部キー列を追加する(のに適した列追加メソッド)。
-
create_table
のt.references
の正体はこれ。
create_table :followers do |t|
t.references :user, foreign_key: true
t.references :follower, foreign_key: true
t.timestamps
end
add_reference(table_name, ref_name, **options)
-
ref_name
(第一引数)- 第一引数は「関係名」とでもいうべきラベルである(多分)。
- 参照先テーブルへの明示的な指定がなければこれはテーブル名(単数形)と解される。
-
foreign_key:
外部キー制約(+インデックス)をつける。-
true
またはadd_foreign_key
メソッドのオプションをそのまま指定する。-
to_table:
参照先テーブル名を明示的に指定する。 -
column:
カラム名を明示的に指定する。 - :
-
-
-
index:
インデックス要否(デフォルトはtrue
) -
null:
ヌル可否 polymorphic:
-
type:
型
-
type:
を指定しないと、勝手に整数型にされ、
参照先のテーブルの主キーが文字列型の場合など、型が一致せず、
妙な不具合が起こることが、少なくとも SQLite3 を使った時起きた。 - 相手型の主キーのそれを
type:
limit:
には指定すべきと覚えておこう。
-
null: true
と指定しても、値がnil
のとき撥ねられることがあった。 - これは、レコード格納以前に、ヴァリデーション で撥ねられていた。
-
belongs_to
にoptional:true
を指定することで、
(validates
ではなくbelongs_to
の話)
外部キーの値がnil
でも、ヴァリデーションが通り、格納できるようになる。class Token < ApplicationRecord belongs_to :user, optional: true end
-
to_table:
に 参照先テーブル名を指定し、
t.references
の第一引数は「関係名」と位置付け、
foreign_key:
の値を(真偽値ではなく)ハッシュにする。
create_table :followers do |t|
t.references :user, foreign_key: { to_table: :users }
t.references :follower, foreign_key: { to_table: :users }
t.timestamps
end
add_foreign_key(from_table, to_table, **options)
-
to_table:
(第一引数) 参照先テーブル名を明示的に指定する。 -
primary_key:
to_table
の主キー列名の指定(デフォルトはid
)-
to_table
が複合主キーの場合は配列での指定。
-
-
column:
from_table
に追加されるカラム名を明示的に指定する。-
to_table
が複合主キーの場合は配列での指定。
-
-
index:
インデックス要否(デフォルトはtrue
) -
on_delete
親レコードの削除時の振る舞い -
on_update
親レコードの更新時の振る舞い
-
公式ドキュメント
ではとても素晴らしいことを書いているが、実際問題としては、
テーブル名(単数系)で指定すると動作しないことがあると思う。
カラム名で指定するのがよいかと思う。- エラー:
one: id: 1 user: user_one
- うまくいく:
one: id: 1 user_id: user-one-id
- エラー:
add_index(table_name, column_name, **options)
インデックスを追加する。
インデックスの一種と位置付けられている。
unique: true
をつける。
create_table :user, id: [:office_code, :desk_no] do |t|
t.string :office_code, limit: 10
t.integer :desk_no
t.string :email
t.timestamps
end
add_index :user, :email , unique: true
add_index :user, [:office_code, :desk_no], unique: true
- 文字列や数値
- 引用符なしでそのまま書いて良い。
- 日付時刻型
- 何分前といった表現が使える(ERB)。
- カラムがヌル
- 値に
null
(または~
)を指定。
- 値に
- バイナリ値を指定したい
- 値を
!!binary |
で始め、次行以降に Base64 形式で書く。
- 値を
user_without_email:
id: s00u9012
name: "User without email"
email: null # または '~'
age: 19
photo: !!binary |
8f8ev6nzZQL9VvpPF9QlkuIlwGn5hj43/mPvAUbo48/zQ+bQ+GHLWLXWk8K+
QW1Ug2Ax/el+6BMV0FjJA3UD2UUvpyaGD6juqIrincwnDYbC2MnLEIeab6R3
:
SLGHBGgh16j74mfEEstpw3g=
updated_at: <%= Time.current.to_s(:db) %>
created_at: <%= 3.days.ago %>