KDOC 690: Railsのモデルのバリデーションは既存のレコードを検査しない
この文書のステータス
- 作成
- 2026-10-18 貴島
- レビュー
- 2026-10-18 貴島
概要
Railsのモデルのバリデーションは、 save や update でデータベースに送る前のオブジェクトにだけ走る。そのため、あとから presence: true を足しても、すでに NULL が入っているレコードはそのまま残る。そのレコードは、ほかのカラムを直して保存しようとしてもバリデーションで弾かれ、ふつうの save や update では更新できなくなる。
既存のレコードまで守るには、 NULL を直してからデータベースに NOT NULL 制約を付ける。ただし presence: true は空文字列も弾くが、 NOT NULL は空文字列を通すので、同じ守りにはならない。
新規レコードを保存すると、SQLのINSERT操作がデータベースに送信され、既存のレコードを更新すると、SQLのUPDATE操作が送信されます。バリデーションは、これらのコマンドがデータベースに送信される前に実行されるのが普通です。
このバリデータの内部では、属性の値がnilや空白(blank: つまり空文字列“”またはホワイトスペースのみで構成される文字列)であることのチェックにObject#blank?メソッドが使われています。
関連
抽象。
- 後から足した検査は、すでにあるデータには適用されない
- 似た制約に見えても、通すものが違う
関連。
- 類似: KDOC 391: 1対1のテーブルを維持する。守りたい制約を、データベースの制約で表せるかアプリ側の規約で守るかの例