はじめに
バリデーションをかける以外の制限について、知らない事が多かったので再学習。
制約とは
リレーショナルデーターベース(RDB)でテーブルにデータを追加・更新する際に課すことができる制約のこと。
NOT NULL制約
各カラムの値に、nilを制限する。
create_table :texts do |t|
t.integer :genre, null: false
t.string :title, null: false
t.text :content, null: false
t.timestamps
end
null: true => 許可(デフォルト)
null: false => 拒否
バリデーションとの違い
NOT NULL制約はnilを弾くことができるが空文字は弾けない
バリデーションはnilも空文字列も弾くことができる。
制限 | nil | 空文字列("") |
---|---|---|
null: fauls | ○ | ✖️ |
presence: true | ○ | ○ |
デフォルト制約
カラムの値に初期値を指定する。
create_table :users do |t|
t.integer :age, null: false, default: 0
t.string :name, null: false
t.text :email, null: false
t.timestamps
end
今回は初期値を0に指定。
一意性制約(ユニーク制約)
テーブル内の重複するデータを制限する。
def change
add_index :users, :email, unique: true
end
上記の場合、usersテーブルのemailカラムにインデックスを追加位して、そのインデックスに一意性の制約をかけるよってこと。
モデルからでもバリデーションをかけられるけど、「Active Recordはデータベースのレベルで一意性を保証していない」という問題がある。
そこでデータベース上の特定のカラムにindexを追加して、そのindexが一意性であるようにすれば解決できる。
indexとは
本の索引機能みたいなもの。データベースに格納されいているデータを片っぱしから探そうとすると非効率だから、indexで効率良く目的のデータまでたどり着くためのもの。
indexの追加
インデックスの追加方法については、「マイグレーションでインデックスを追加するだけ」
rails generate migration add_index_to_テーブル名_カラム名
忘れずrails db:migrateすること
主キー制約(プライマリーキー制約)
テーブル内の重複するデータとNULLを制限する。
create_table :users id: false do |t|
t.integer :age, null: false, default: 0
t.string :name, null: false, primary_key: true
t.text :email, null: false
t.timestamps
end
主キーはcreate_tableによってidという名前の主キーが作成される。
主キーを変更したい場合は:primary_keyオプションで指定する。
主キーを使いたくない場合はid: falseオプションで指定する。
外部キー制約(フォーリングキー制約)
親テーブルと子テーブルの整合性を保つための制限をかける。
外部キー制約が設定された子テーブルのカラムは、親テーブルのカラムに格納されている値しか格納することができなくなる。
add_foreign_key :テーブル名(参照元), :テーブル名(参照先)
上記では、新たな外部キーが参照元テーブルのidカラムに追加され、参照先テーブルのidカラムを参照する。
カラムを指定する場合
add_foreign_key :テーブル名(参照元), :テーブル名(参照先), column: :カラム名(参照先), primary_key: カラム名(参照先主キー)
参照先はt.references :テーブル名で宣言する必要がある。
参考もと
【Rails】「テーブルのカラムに定義するNot Null制約」と「モデルに定義するバリデーション(presence: true)」の挙動の違い。
Railsガイド/Active Record マイグレーション
Railsで主キーをid以外に設定し、ほかのテーブルとアソシエーションを結ぶ