LoginSignup
46
36

More than 3 years have passed since last update.

【Rails】初めてのDB設計

Last updated at Posted at 2020-07-04

SQL(Structured Query Language)とは

  • リレーショナルDB(RDB)に命令を行う言語。
  • ISO(国際標準化機構)で規格化されており、どんなリレーショナルDBにも、同じ文法で操作する。
  • リレーショナルDB(RDB): Webアプリで一般的に使用される、表形式でデータ管理するDBのこと。(例:MySQL、PostgreSQL、SQliteなど)
  • 命令は2つに分類。
    定義: DDL(Data Definition Language)
    操作: DML(Data Manipulation Language)

【DDLの命令】

命令 機能
CREATE DB、テーブル作成
ALTER DB、テーブル更新
DROP DB、テーブル削除

【DMLの命令】

命令 機能
INSERT データ登録
UPDATE データ更新
DELETE データ削除
SELECT データ検索

ターミナルでのSQL文実行

  • SQLの実行には、DBへの接続が必要なので、以下のコマンドでmysqlrootユーザーで接続すると、MySQLが起動し、SQL文でMySQLが操作できる。
ターミナルでのSQL操作
-- mysqlに接続
 % mysql -u root

-- 今まで作ったDBの一覧表示
 mysql> SHOW DATABASES;

-- DB作成
 mysql> CREATE DATABASE DB;

-- DBを選択
 mysql> USE DB;

-- DB内のテーブル一覧表示
 mysql> SHOW TABLES;

-- テーブル作成
 mysql> CREATE TABLE テーブル名 (カラム名 カラム名の型, ……);
 mysql> CREATE TABLE items (id INT, name VARCHAR(255));
  -- ※ rails g model モデル名 でテーブルに紐づくモデルとマイグレーションファイルを作成/実行(rake db:migrate)するのと同義。
  -- ※ rake db:migrate で、 CREATE TABLE というSQL文が動いてる

-- テーブル構造(カラム名、カラム型、制約など)の確認
 mysql> SHOW columns FROM テーブル名;
 mysql> SHOW columns FROM items;

-- テーブル構造の変更(カラムの追加・修正・削除など)
 mysql> ALTER TABLE テーブル名 操作
 -- カラム追加
  mysql> ALTER TABLE テーブル名 ADD カラム名 カラム型;  -- 1つ追加
  mysql> ALTER TABLE テーブル名 ADD (カラム名 カラム型, ……);  -- 複数追加
  mysql> ALTER TABLE items ADD (price int, zaiko int);
 -- カラムの修正 (カラム型は変更がなくても、書く必要がある!)
  mysql> ALTER TABLE テーブル名 CHANGE 古いカラム名 新しいカラム名 新しいカラム型;
  mysql> ALTER TABLE items CHANGE zaiko stock int;
 -- カラムの削除
  mysql> ALTER TABLE テーブル名 DROP カラム名;
  mysql> ALTER TABLE items DROP stock;


 -- データの登録
  -- 全カラムに値を入れる場合
   mysql> INSERT INTO テーブル名 VALUES(1, ...);
  -- 特定カラムのみに値を入れる場合 (指定しないカラムはデフォルト値(NULL)が入る)
   mysql> INSERT INTO テーブル名(カラム名1, ...) VALUES(1, ...);  
   mysql> INSERT INTO items VALUES(1, "ペン", 120);
   mysql> INSERT INTO items(id, name) VALUES(2, "消しゴム");

 -- テーブルの全レコード表示
  mysql> SELECT * FROM items;

 -- データ更新
  mysql> UPDATE テーブル名 SET 変更内容 WHERE 条件;
  mysql> UPDATE items SET price = 100 WHERE id = 2;

 -- データ削除
  mysql> DELETE FROM テーブル名 WHERE 条件;
  mysql> DELETE FROM items WHERE id = 2;

-- mysqlを終了
 mysql> exit
SQL文 機能
SHOW DATABASES 文 DB一覧表示
CREATE DATABASE 文 DB作成
CREATE TABLE 文 テーブル作成
USE 文 DBを選択
USHOW TABLES文 DB内のテーブル一覧表示
ALTER TABLE 文 カラムの追加・修正・削除
INSERT 文 テーブルにデータ登録
UPDATE 文 テーブルのデータ更新
DELETE 文 テーブルのデータ削除
  • SQL文の終わりは ;を付ける。
    (忘れたら、SQLがまだ続くとみなされ、-> が表示されるので、;を入力すればOK)。
  • カラム型の(例) INT:数字、VARCHAR(●):最大●文字の文字列

クエリでのSQL文実行

  • 検索では、クエリから実行する。理由は、

    1. 検索では、SQL文が長くなるので、タイプミス時の修正が容易
    2. 検索結果の出力も長くなっても、SQL文が流れず、見やすい
    3. SQL文の文末の ;が不要。
  • クエリ(例えば、SequelPro)でのSQL文の実行方法は、上画面にSQL文を書き、現在を実行をクリックすると実行される。

  • SELECT句(テーブルの指定) + FROM句(取得するカラムの指定)が、検索の基本構造。

  • WHERE句: 取得するレコードを制限。条件式は、
    比較演算子(<、>、..)、
    AND演算子(and、or)、
    BETWEEN演算子(上限と下限の指定)、
    IN演算子(1つのカラムにリストを指定し、値がリストに含まれる時 true)、
    NOT演算子など。

  • ワイルドカード : 文字の代わりに使える記号のこと。*は全部の意味。

クエリでの検索
-- SQL文のコメントアウト

-- 検索の基本構造
 SELECT カラム名  -- 取得カラムの指定
 FROM テーブル名  -- 検索するテーブルの指定
 WHERE 条件     -- 取得レコードの制限
 -- (例)全カラムを取得、レコードの検索条件を指定
  SELECT *
  FROM users
  WHERE age <= 22 AND prefecture = "神奈川県"
 -- (例)
  SELECT *
  FROM users
  WHERE age <= 20 OR prefecture = "東京都"
 -- (例)
  SELECT *
  FROM users
  WHERE age BETWEEN 21 AND 24
 -- (例)
  SELECT *
  FROM users
  WHERE NOT prefecture = "東京都"
 -- (例)
  SELECT *
  FROM users
  WHERE prefecture IN ("東京都", "神奈川県")

-- 検索データの結合
 CONCAT(文字列1, 文字列2, ..) -- 文字列の連結
 -- (例)フルネームを出力する場合(通常、カラム名はSQL文になる)
  SELECT CONCAT(family_name, first_name)
  FROM users
 -- (例)フルネームを出力する場合(カラムに別名を付ける場合)
  SELECT CONCAT(family_name, first_name) AS "名前"  -- AS は省略可
  FROM users

-- 重複する行の除外
 SELECT DISTINCT カラム名
 -- (例)shiftsテーブルから、date = "2015-07-01"のカラム取得(重複するuser_idを除く)
  SELECT DISTINCT user_id
  FROM shifts
  WHERE date = "2015-07-01"

-- レコードのグループ化
 GROUP BY カラム名
 -- (例)shiftsテーブルからdate="2015-07-01"に誰がシフトに入ったかを取得("user_id"が同じものをグループ化し、"user_id"表示)
  SELECT user_id
  FROM shifts
  WHERE date = "2015-07-01"
  GROUP BY user_id

-- レコード数を数える
 SELECT COUNT(カラム名)
 SELECT COUNT(*)  -- 全部の値がNULLのレコードも含めた行数を取得
 -- (例)shiftsテーブルからdate="2015-07-01"に、誰が、何コマずつシフトに入ったかを取得(カラムにコマ数という別名を付ける)
  SELECT
    user_id,
    COUNT(*) "コマ数"
  FROM shifts
  WHERE date = "2015-07-01"
  GROUP BY user_id

-- テーブルの結合(テーブル1にテーブル2を結合(条件:テーブル1のカラム1がテーブル2のカラム2と一致するもの))
 FROM テーブル名1
 JOIN テーブル名2 ON テーブル名1.カラム名1 = テーブル名2.カラム名2
 -- (例)shiftsテーブルにusersテーブルを結合。(shiftsテーブルの"user_id"がusersテーブルの"id"と一致する行を結合)
  FROM shifts
  JOIN users ON shifts.user_id = users.id
 -- ↑は普通、簡略して書く!(テーブルに別名で扱う。テーブル名の頭文字が一般的。)
  FROM shifts s
  JOIN users u ON s.user_id = u.id
 -- まとめて書くと、
  SELECT
    CONCAT(family_name, first_name) "名前",
    COUNT(*) "コマ数"
  FROM shifts s
  JOIN users u ON s.user_id = u.id
  WHERE date = "2015-07-01"
  GROUP BY user_id

-- サブクエリ:検索結果を用いた検索(例えば、↑の検索に該当しないデータの取得とか)
 SELECT *
 FROM users
 WHERE id NOT IN (
   SELECT DISTINCT user_id
   FROM shifts
   WHERE date = "2015-07-01"
 )
IN演算子(カラム名に値1、もしくは、値2、...を含む場合true)
-- (値1, 値2, ……)部分がリスト
 WHERE カラム名 IN (1, 2, ……)
-- ↑と同義
 WHERE カラム名 = "値1" OR カラム名 = "値2" OR ...
  • CONCAT 関数: 複数の文字列を連結する関数(※文字列にNULLがあれば、結果はNULL)。
  • AS 句: CONCAT 関数での検索結果のカラム名は、SQL文のままで見にくいので、検索結果のカラム名の変更する時に使う。
  • DISTINCT キーワード: 指定カラムの値が重複する行を除外して取得。
  • GROUP BY 句: 指定カラムが同じ値のデータをグループにまとめる(表示されないデータもそのグループに保持されてる)。
    DISTINCTと似てるが、GROUP BYは、グループ単位で集計した結果を取得できることが利点。
  • COUNT 関数: グループ化したデータに使える集計関数。カラムを指定して使用することで、値がNULLでない行数を取得できる。
    GROUP BY句を併用すると、各グループが持つレコードの数を取得できる (※ グループ化データに使える集計関数は、他に、平均AVG、最大値MAX、最小値MINなど)。
  • JOIN 句: 指定テーブルの、カラムが同じデータを結合。FROM句の後に書き、結合する対象テーブルを指定。JOINにはINNER JOINLEFT JOINRIGHT JOINなど、結合法則の違うものがある。
  • サブクエリ: 検索結果を使って、別のSQL文を実行する仕組みのこと。WHERE句で使うことが多いが、SELECT句やFROM句でも使える。

DBとは

  • DB構成要素:3つ(サービスで扱う概念(エンティティ)、エンティティの属性、エンティティ間の関係性(リレーション))。
    エンティティ: サービスで管理する必要のある概念(情報、データ)のこと。テーブルにあたる。(例: ユーザー、投稿内容、コメント)
    エンティティの属性: エンティティが持つ個別情報のこと。カラムにあたる。(例: タイトル、説明、公開日、監督)
    リレーション: エンティティ間の関係性のこと。(例:映画-を監督)

  • 属性の中にはキー(テーブル内のレコード同士を識別するための被らないデータ)が存在する。 主キー 、 外部キー の2種類ある。
    主キー: テーブル内のレコードを判別のための識別子カラム(多くの場合、id)。
    外部キー: 関連する他のテーブルの主キー(カラム)と関係がある時に必要なカラム。他のテーブルのレコードとのリレーションを表すために使う。

DB設計

  • サービスに必要な情報の管理方法を決める作業。
  • 【DB設計の手順】
    1. 必要な機能を洗い出す。(ページの繋がりを把握から考えてみる)
    2. 洗い出した機能に、管理したいエンティティ(必要なデータ)を抽出する。
    3. データの持つ属性を決める。テーブルの分け方も考える。
      ※ データ変更・削除しないテーブルは、active_hashかenumを使えないか?も考えてみる。
    4. テーブルの繋がり(リレーション)を決める(ER図)。
      ER図とは? : Entity-Relationship Diagramの略、テーブル間の関係を視覚的に表した図(IE表記法 で書く)。

テーブル作成

モデル + マイグレーションファイルを作成

テーブル作成
$ rails g model モデル名

テーブル変更

マイグレーションファイルのみ作成。※ 名前は何でもok。

テーブル変更
$ rails g migration マイグレーション名
 $ rails g migration DropUser
# カラム追加
 $ rails g migration Addカラム名Toテーブル名 カラム名:
 $ rails g migration AddNameToUsers name:string
# カラム削除
 $ rails g migration Removeカラム名Fromテーブル名 カラム名:
# カラム名変更
 $ rails g migration RenameFrom変更前のカラム名To変更後のカラム名Onテーブル名
# カラムの Null制約変更
 $ rails g migration ChangeColumnToNotNull
# カラム変更
 $ rails g migration ChangeColumnToUser
# 外部キー削除
 $ rails g migration AddArticleToUsers article:references

# テーブル作成時に外部キーをreferences型カラムで保存
 $ rails g model モデル名(大文字単数) カラム名:references
 $ rails g model UserAccount user:references # 外部キー作成

$ rails g model User uuid:string:unique name:string

マイグレーションの実行・確認・取下げ・編集・削除

マイグレーション実行
$ rails db:migrate  # rails4までは、rakeコマンド
マイグレーションの確認
$ rails db:migrate:status
  up:実行済み、down:実行前の状態

※ schema_migrationsテーブルにもマイグレーションファイルのバージョンが保存されている(version:××××××)。
※ スキーマファイル(schema.rb):最新のテーブル一覧が記録されている。

実行済みのマイグレーション取下げ
$ rails db:rollback
 up  downの状態になる。
# 新しいものから2つのファイルを同時にロールバック
 $ rails db:rollback STEP=2

※ upの状態でマイグレーションファイル削除すると、エラーに繋がるので、down状態を確認してから削除!

マイグレーションをリセットして再実行(変更済みのマイグレーションを変更・削除するときとか。。)
# DBを削除後に、db/migrate/**.rb を古い順から実行
 % rails db:migrate:reset

# マイグレーションファイルの順番に問題がある場合、NGになることがある。
# そんな時は、分けて実行すると行ける場合がある。
 % rails db:reset   # db/schema.rbを元にDB作成
 % rails db:migrate
マイグレーションファイルの編集(テーブル作成)
def change
  create_table :hoges do |t|
    t.カラムの型   :カラム名
    t.string     :name
    t.text       :text
    t.references :user, index: true, foreign_key: true
    t.timestamps
  end
end
マイグレーションファイルの編集(カラム追加)
def change
  # カラム追加
  add_column    :テーブル名, :カラム名, :
  # カラム削除
  remove_column :テーブル名, :カラム名, :
  remove_columns :テーブル名, :カラム名, :カラム名,  :カラム名
  # カラム名変更
  rename_column :テーブル名, :変更前のカラム名, :変更後のカラム名
  # カラムの制約、オプションを変更
  change_column :テーブル名, :カラム名, :
  change_column :users, :name, :string, null: false
  change_column :users, :name, :string, limit: 10
  change_column :users, :uuid, :string, null: false, default: 0
  change_column :テーブル名, :カラム名, :, null: true  # NULL制約
  change_column :テーブル名, :カラム名, :, null: false  # NOT NULL制約
  change_column :テーブル名, :カラム名, :, index: true  # インデックス
  change_column :テーブル名, :カラム名, :, default: "piyo"  # デフォルト
  change_column :テーブル名, :カラム名, :string, limit: 12  # 長さ varchar(12)
  change_column :テーブル名, :カラム名, comment: "コメントです"  # コメント
  # テーブル作成
  create_table :テーブル名
  drop_table   :テーブル名
  # テーブル名変更
  rename_table  :現在のテーブル名,  :新しいテーブル名
  # インデックスをつける
  add_index  :テーブル名,  :インデックスを付けるカラム名 [, オプション])
  add_index :company, :company_name
  add_index :users, [:name, :name2]
  add_index :user_accounts, [:provider, :uid], :name => 'unique_provider_uid', :unique => true
  # インデックスを削除
  remove_index :テーブル名, :カラム名
  remove_index :company, name: :company_name_fk
  # 外部キーを追加
  add_reference  :テーブル名,  :リファレンス名 [, オプション]
  add_reference  :hoges,  :user, foreign_key: true
  add_reference :テーブ名, :カラム名, index: true

  add_foreign_key :対象テーブル, :指定先テーブル, :column :対象のカラム名
  add_foreign_key  :テーブル名,  :指定先のテーブル名 [, オプション]
  add_foreign_key :対象のテーブル, :指定先のテーブル, name: :foreign_keyの別名
  add_foreign_key :companies, :accounts
  add_foreign_key :companies, :accounts,  name: :huga_id  # 別名をつける場合
  add_foreign_key  :trades,  :users, column: :seller_id  # seller_idカラム対して外部キー制約をつける場合
  # 外部キーを削除
  remove_foreign_key  :テーブル名,  :指定先のテーブル名
  remove_foreign_key :users, column: :article_id  # 外部キー削除
  remove_reference :users, :article, foreign_key: true  # カラムも一緒に削除する場合
end

Rails5では、デフォルトでidはbigintで、参照元テーブルのカラムをintegerで作成するとforeign keyが作成できない。なので、テーブルのカラムをbigintで作成して、外部キーを設定すると良さそう!!

マイグレーションファイルでよく使うメソッド

メソッド名 概要
add_column カラム追加
remove_column カラム削除
remove_columns 複数カラムを削除
rename_column カラム名変更
change_column カラムの情報変更
create_table テーブル作成
drop_table テーブル削除
rename_table テーブル名変更
add_index インデックス追加
remove_index インデックス削除
add_reference 外部キー作成
remove_reference 外部キー削除
add_foreign_key 外部キー制約付与
remove_foreign_key 外部キー制約削除

カラムの型

カラム型 概要
string 文字(〜255文字)
text 文字(255文字〜)
integer 通常の整数
smallint 狭範囲の整数
bigint 大きな整数
float 小数点を含む数
decimal, numeric 大きな数 ※桁数などを指定する時
boolean 真/偽
time 時刻 12:00:00
date 日付 2020-01-01
datetime 日時 2001-01-01 01:01:00
timestamp タイムスタンプ
json JSONで保存
binary 画像などをバイナリデータにしたい時
references 外部キー

制約

特定のデータを保存さないためのバリデーション。

制約の種類 記述 概要
NOT NULL制約 null: false カラムに設定する制約。NULL(空)では保存さない(エラーにする)。必須項目に使う。
一意性制約 unique: true カラムに設定する制約。テーブル内で重複データの保存を禁止する
主キー制約 - フォーマットで設定。主キーの属性値が存在し、かつ、重複しないことを保証する。主キーへの NOT NULL制約 + 一意性制約と同義。
外部キー制約 foreign_key: true 外部キーに対応するレコードが存在することを保証する
外部キーのnilを許可 optional: true 外部キーが空でも保存を可能にする

※ 外部キーのカラム名を指定したい時

モデル
 belongs_to :user, foreign_key: :seller_id

インデックス

  • DBの機能の1つで、テーブル内のデータの検索速度向上のための仕組み。索引(目次)のイメージ。
  • 検索に使うカラムに使う。
  • インデックスを貼るメリット: データの読み込み/取得速度向上
    (牽引で目的の場所を見つけ、データを読み取るため)
  • インデックスを貼るデメリット: DBの容量が圧迫されるのと、書き込み速度低下
    (インデックスは、テーブルのデータとは別の領域に保存されるので、データを書き込む時(保存/更新)、テーブルへの書き込み、インデックスへの書き込みが必要なため)
  • 複数カラムにインデックスを貼れるが、カラム単体で検索する時は、検索速度は向上しないので、その複数カラムのセットでめっちゃ検索する場合だけ、複数カラムにインデックスを貼る
マイグレーションファイル
def change
  add_index :テーブル名, :カラム名
end

正規化

  • DBのデータ構造を無駄のないシンプルな構造にする手順。
  • 正規化後のDB構造を正規形、正規化していないDB構造を非正規形という。
  • 正規化順番: 非正規形 → 第1正規形 → 第2正規形 → 第3正規形 → ボイスコッド正規形 → 第4正規形 → 第5正規形。(第4正規形以降は、パフォーマンス低下の可能性があり、第三正規形に留めるのが一般的。)
  • 正規化のデメリット: 正規化は進めるほどに、パフォーマンスが低下する。小さなテーブルが増えていくことが理由。関連テーブルの検索のたびにSQL実行回数が増え、速度低下するため、第3正規形で終えることが多い。

【テーブルの問題点】
重複するカラム:冗長なDBになる。
1つのテーブルに複数の情報(エンティティ)が混在:可読性を含め、パフォーマンスが低下。
この問題を解決するのが正規化

正規化の順番

  • 第1正規形: 同一カラムが存在しない、かつ、レコードを構成する1つのマスに、値が1つずつ入る状態にすること。
  • 第3正規形: 第2、第3正規形は似ており、違いは複雑な概念のため、第2正規形は割愛。第3正規形は、主キーに依存、かつ、非キー属性(主キーでないもの)同士の依存がない状態にすること。
  • 混在したエンティティは、属性ごとにテーブルを分ける。

N+1 問題

モデルでDBへアクセス時、SQLが発行される。アソシエーションで、子モデルのインスタンスを複数取得する時は、N+1問題を考慮し、includesメソッドなどで解消する!

モデルでアソシエーション定義

  • 1 対 多: has_many :複数belongs_to :単数
  • 1 対 1: belongs_to :単数。所有(まるごと含む)場合は、has_one :単数
  • 多 対 多: 中間テーブルを作成。has_many through オプション↓↓
多対多モデル
has_many :相手のテーブル名, through: :中間テーブル名

# 中間テーブル
belongs_to :テーブル名1
belongs_to :テーブル名2


# アソシエーション定義すると、自動で以下のメソッドが使えるようになる。
 # 通常のレコード作成
 変数名1 = モデル名1.create(カラム名: "値", ..)  # 単体のインスタンス生成
 変数名2 = モデル名2.create(カラム名: "値", ..)
 # 多対多を定義したレコード作成
 変数名1.相手テーブル名2(複数形).create(カラム名: "値", ..)    # 多対多の関係を使って、変数名1に関係する相手テーブル名2のインスタンス生成
 # リレーション追加
 変数名1.相手テーブル名2(複数形) << 変数名2   # 後からインスタンス同士を関連付けも可能
 # 変数名1と関係する相手テーブル名2の配列に、モデル名1のインスタンス追加でリレーション生成。

 # リレーションを利用したレコード取得
 変数名.相手テーブル名(複数形)  # リレーションしている要素を全て出力(返り値は、関連付けられているインスタンスが出力される)

モデルでバリデーション定義

モデル(詳細は、公式ドキュメントを参照)
# 汎用的に使うバリデーション
validates(フィールド名, 種類 [, オプション])
  validates :form, acceptance: true   # チェックボックスがオン?
  validates :form, acceptance: false  # チェックボックスがオフ?
  validates :email, confirmation: true  # テキストフィールドが一致するか?
  validates :email, confirmation: false  # テキストフィールドが一致しないか?
  validates :subdomain, exclusion: {in: %w(www us ca jp)}   # 含まないか?
  validates :legacy_code, format: {with: /\A[a-zA-Z]+\z/}   # 正規表現と一致するか?
  validates :size, inclusion: {in: %w(small medium large)}     #  含むか?
  validates :name, length: {minimum: 2}   # 長さ
  validates :points, numericality: true   # 数値のみか
  validates :name, :login, :email, presence: true   # 空で無いか?
  validates :name, :login, :email, absence: true   # 空か?
  validates :email, uniqueness: true   # 重複してないか?

# 一意
validates_uniqueness_of(フィールド名 [, オプション])

# 関連付けたモデルもバリデーション(関連が無い場合はバリデーションは成功)
validates_associated(対象 [, ...])

# 空でないか
validates_presence_of(対象 [, ...])
# 空であるか
validates_absence_of(フィールド名 [, ...])
# チェックボックスにチェックが入っているか
validates_acceptance_of(フィールド名 [, ...])

# 2つのフィールドが等しいか
validates_confirmation_of(フィールド名 [, ...])

# 値が配列・範囲に含まれてないか
validates_exclusion_of(フィールド名 [, ...])
# 値が配列・範囲に含まれるか
validates_inclusion_of(フィールド名 [, ...])

# 正規表現パターンに一致するか
validates_format_of(フィールド名 [, ...])

# 文字列の長さ
validates_length_of(フィールド名 [, ...])

# 数値の大小、型
validates_numericality_of(フィールド名 [, ...])

# バリデーションの別クラスにレコードを渡し、複雑な条件のエラーを追加
validates_with(引数)

# ブロックに対してのバリデーション
validates_each(キー名, [,  オプション])

バリデーションの種類

validates の種類 概要
:acceptance チェックボックス入力
:confirmation テキストフィールドが一致するか
:exclusion 含まないか
:format 正規表現と一致するか
:inclusion 含むか
:length 長さ
:numericality 数値のみか
:presence 空で無いか
:absence 空か
:uniqueness 重複

バリデーションのオプション

オプション 概要
:message 失敗時の表示メッセージ
:scope 一意性制約したい他のカラム
:conditions 検索条件
:case_sensitive 大/小文字の区別、(デフォルト true)
:on 実行タイミング、(デフォルト 保存時)
:allow_nil nilをスキップ、(デフォルト false)
:allow_blank nil、空文字をスキップ、(デフォルト false)
:if バリデーション条件
:unless バリデーションしない条件
:strict 失敗時の例外処理
:with 正規表現パターン
:without 正規表現パターン
:multiline 行の先頭 or 末尾
:within 比較する配列、範囲

長さに関するオプション

オプション 概要
:minimum 最小値
:maximum 最大値
:in、 :within 範囲内か
:is 等しいか?
:too_long :maximum違反時のエラーメッセージ
:too_short :minimum違反時のエラーメッセージ
:wrong_length :is違反時のエラーメッセージ
:tokenizer 文字列の分割方法

数値、型に関するオプション

オプション 概要
:only_integer 整数か
:greater_than 指定値より大きいか
:greater_than_or_equal_to 指定値以上か
:equal_to 指定値と等しいか
:less_than 指定値より小さいか
:less_than_or_equal_to 指定値以下か
:other_than 指定値以外か
:odd 奇数か
:even 偶数か
46
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
36