どうもこんにちは。
今回は小さなことを書きます。
Railsのバリデーションの設定方法
Railsアプリケーションで、バリデーションを設定するとき、以下のように設定をすると思います。
class User < ApplicationRecord
# ...省略...
validates :department_id, presence: true
# ...省略...
end
アソシエーションがある場合
しかし、アソシエーションがある場合、上記のvalidatesを記述してしまうとエラーメッセージが表示されてしまいます。
仮に、departmentsテーブルとusersテーブルに1対多のリレーションが存在する場合、以下のように記述をすると思います。
class User < ApplicationRecord
# アソシエーションを記述
belongs_to :department
# バリデーション
validates :department_id, presence: true
# ...省略...
end
このように記載をしてしまうと、以下のような二つのエラーメッセージが表示されます。
department が入力されていません
department_id が入力されていません
エラーメッセージが2つ表示される原因
app/models/user.rbに記述したbelongs_to :userは、デフォルトで関連の存在をバリデートします。
department が入力されていません
対処方法
その1: validates行を削除する
以下のように、validates行をコメントアウトするなり削除するなりすることで、表示されるバリデーションメッセージを1つにすることができます。
class User < ApplicationRecord
# アソシエーションを記述
belongs_to :department
# バリデーション
# validates :department_id, presence: true
# ...省略...
end
department が入力されていません
その2: optional: true を指定する
以下のように、belongs_toにoptional: trueを指定することで、バリデートを無効にすることができます。
class User < ApplicationRecord
# アソシエーションを記述
belongs_to :department, optional: true
# バリデーション
validates :department_id, presence: true
# ...省略...
end
この場合は、validatesのバリデーションが動作するので、以下のエラーメッセージが表示されます。
department_id が入力されていません
アソシエーション対象の外部キーカラムが任意項目である場合
belongs_toでアソシエーション定義したモデルがそもそも任意項目である場合も、optional: trueを指定する必要があります。これを指定しないと、nullが許容されません。