railsでbooleanのカラムにprecentを付けてバグらせた
railsでバリデーションの貼り方をミスってバグを生んでしまったのでメモ
結論
booleanのカラムに対して、presenceのvalidationを貼ってはいけない。
バグを起こしたコード
class User < ApplicationRecord
# アプリケーションレイヤーのバリデーションで入力必須にする
# is_deletedがバグの原因
validates :email, :user_name, :is_deleted, presence: true
end
29] pry(main)> user.errors
=> #<ActiveModel::Errors:0x00007f800e8ef3d8
@base=
#<User:0x00007f800e01f348
id: nil,
email: "hogehgoe@gmail.com",
user_name: "hoge",
is_deleted: false,
created_at: nil,
updated_at: nil>,
# is_deletedは存在しているのにないよって言われている
@details={:is_deleted=>[{:error=>:blank}]},
# is_deletedがfalseなのでこけていた
@messages={:is_deleted=>["can't be blank"]}>
原因
presenceは内部的にblankを使用しているので、falseも存在しないと判定されてしまう。
2.9 presence
このヘルパーは、指定された属性が「空でない」ことを確認します。値がnilや空文字でない(つまり空欄でもなければホワイトスペースでもない)ことを確認するために、内部でblank?メソッドを使っています。
# blankの挙動
[83] pry(main)>
[84] pry(main)> nil.blank?
=> true
[85] pry(main)> "".blank?
=> true
# falseもtrueになる
[86] pry(main)> false.blank?
=> true
[87] pry(main)>
反省
ドキュメントをちゃんと読む😢
本番リリース前でよかった〜