見出し画像

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分程なので最後まで見れます。

以上。最後まで読んでいただきありがとうございました!!



いいなと思ったら応援しよう!