#マイグレーションの適用を理解する
DBのマイグレーションは、1つのマイグレーションが1つのバージョンとして扱われるので、1つのマイグレーションを適用することでバージョンを1つ上げることができ、適用済みのマイグレーションを1つ取り消すことでバージョンを1つ下げることができます。
rails g migrationコマンドで生成されるファイルのchangeメソッドの処理は、コマンド rails db:migrate でバージョンが上がり、コマンド rails db:rollbackでバージョンが下がります。このchangeメソッド内の処理は自動的に、適切に処理してくれます(例外あり)。
##schema.rb
Railsは現在のDBの構造はdb/schema.rbに自動出力されます。マイグレーションの適用や外しで自動的に出力されます。
#データ内容の制限
データには想定される「内容の範囲」があり、そぐわない値が格納されないようできるものがあります。
一般的に以下の4つがRailsアプリでよく利用されます。
- データ型
- NOT NULL制約
- 文字列カラムの長さの制限
- ユニークインデックス
#データ型
DBのカラムには型を指定します。主なデータ型は以下の表です。
データ型 | 説明 |
---|---|
:boolean | 真偽値 |
:integer | 符号付き整数 |
:float | 浮動少数点数 |
:string | 文字列(短い文字列) |
:text | 文字列(長い文字列) |
:date | 日付 |
:datetime | 日時 |
#NOT NULL制約
DBのカラムの値としてNULL(空の値)を格納する必要がない場合は、NOT NULL制約を物理的にNULLを保存できないようにしてくれます。
作成した投稿アプリでは、Postモデルの「投稿内容」(content)につけるのが適当でしょう。
postsテーブルのcontentカラムにNOT NULL制約をつける、つまり既に作ってあるテーブルに制約をつける場合にも、マイグレーションを利用します。
マイグレーションを作るには、まずgeneratorを使って雛形ファイルを生成します。名前は「ChangePostContentNotNull」とします。
bin/rails g migration ChangePostsContentNotNull
Running via Spring preloader in process 10646
invoke active_record
create db/migrate/XXXXXXXXXXXX_change_posts_content_not_null.rb
雛形を生成したら、ファイルの中身を次のように編集します。
class ChangePostsContentNotNull < ActiveRecord::Migration[5.2]
def change
change_column_null :posts, :content, false
end
end
change_column_nullのtrue,falseでNOT NULL制約のつけはずしができます。
編集を終えたたら、マイグレーションを実行して完了です。
#文字列カラムの長さ指定
DBのカラム定義で、必要以上に長いデータの保存を防ぐことができます。マイグレーションで文字列カラムに対してlimitオプションを使います。
今回は投稿内容(content)を50文字に制限する処理を書いて、適用しています。
class ChangePostsContentLimit50 < ActiveRecord::Migration[5.2]
def up
change_column :posts, :content, :text, limit: 50
end
def down
change_column :posts, :content, :text
end
end
change_columnでは、バージョンを戻す際の処理を、バージョンを上げる際のコードから自動生成できません。そのため、changeメソッドではなくupメソッドにバージョンを上げる処理、downメソッドにバージョンを下げる処理を書いています。
#ユニークインデックス
あるテーブルのあるカラムのデータが、全レコード内で一意である(他と被らない)場合には、ユニークインデックスを作成することで一意性を確保できます。仮にcontentにユニークインデックスを追加したい場合は以下のようなファイルを作ると良いでしょう(実際には行っていません)。
class AddIndexToPosts < ActiveRecord::Migration[5.2]
def change
add_index :content, unique: true
end
カラムにユニークインデックスを追加することで、重複した値がDBに存在することが防げます。
なお、NULL同士は常に異なる値だとみなされるので、ユニークインデックスを追加したカラムの値がNULLのレコードは複数存在することができます。