Rails 一意性制約のかけ方
Railsでアプリ開発中にバリデーションをかけようと思い、
一意性制約(テーブル内で重複するデータを禁止する)の記述について、ネットで調べていると、
unique:true
uniqueness: true
上の2つで出てきて、どっち!?違いはなに!?ってなったんで調べてみました。
まず前提として一意性制約には以下の2パターンのやり方があるという事。
①アプリケーション側に設定➔モデルに記述(uniquness:true)
②DB側に設定➔マイグレーションファイルに記述(unique:true)
まず①についてはこんな書き方
class User < ApplicationRecord
validates :name, uniqueness: true
end
user.rb
続いて②についてはこんな感じ
class AddEmailToUsers < ActiveRecord::Migration
def change
add_column :users, :email, :string
add_index :users, :email, unique: true
end
end
マイグレーションファイル
テーブルのカラムに一意性制約をかけるときは、インデックスの作成も必要になります。全てのデータを検索しないと、過去のデータと重複しているかわからないためです。add_indexメソッドの中でunique: trueと記述します。
一意性成約どっちを使えばいいのか!?
①アプリ側②DB側と2つのやり方があると紹介しましたが、結局どっちを使えばいいのか。答えは両方です。どっちか片方だけでも絶対ダメというわけではないですが、アプリの安全性を考慮すると両方に設定するのがベストです。
一意性成約の問題点 アプリ側のみに設定の場合
可能性としてはかなり低いですが、例えばA君、B君がいたとして、この二人が全く同じタイミングで「山田太郎」というユーザー名でユーザー登録をしたとします(登録のボタンを同時に押す)。
すると何が起きるかというと、一意性制約をかけているにも関わらず「山田太郎」というユーザーが二人作成されてしまい、DBに保存されることがありえるようです。
この事態を回避する為にDBへの一意性成約も必要になるということです。
アプリ側とDB側と両方からダブルチェックしてエラーの可能性をつぶすってこと。
まとめ
・一意性制約は①アプリ側②DB側の2つのやり方がある。
・エラーの防止には両方に一意性成約を設定するのがベスト
一意成約の問題点についてはRuby on Railsチュートリアルの解説動画(第6章 後編: 8. 一意性の問題)がめちゃくちゃわかりやすいです。自分もこれを見るまで完全に理解が出来なくて悩みました。解説動画は基本有料になるみたいですが、メールアドレスを登録すると30分無料で見れます。肝心の箇所は10分程なので最後まで見れます。
以上。最後まで読んでいただきありがとうございました!!