presence: true はboolが入るカラムでは正常に動作しない
結論:
code:ruby
# model-validation
# shoulda-matchers利用したrspec
it { is_expected.to allow_value(true).for(:active) }
it { is_expected.to allow_value(false).for(:active) }
なお先輩はこの程度であればなくてもいい とのこと。確かにです。
not null制約やデータ型がDBレイヤでも保証されており、意図しないデータが登録される可能性がとても低いため
調査:
presence の動作を定義している ActiveModel::Validations::PresenceValidator を見ると
class PresenceValidator < EachValidator
def validate_each(record, attr_name, value)
record.errors.add(attr_name, :blank, options) if value.blank?
end
end
となっています。ここで注目すべきは if value.blank? です。ここで、value には false が入っているわけですが、そうなると…
irb> value = false
=> false
irb> value.blank?
=> true
となり、エラーとして認識されてしまいます!
正しい Boolean フィールドのチェック方法
Booelan のバリデーションを行う場合には ActiveModel::Validations::InclusionValidator (validates に書くときは inclusion) を使って
とするのがいいらしいです。
code:ruby
it { is_expected.to validate_inclusion_of(:active).in_array(true, false) } Warning from shoulda-matchers:
You are using validate_inclusion_of to assert that a boolean column
allows boolean values and disallows non-boolean ones. Be aware that it
is not possible to fully test this, as boolean columns will
automatically convert non-boolean values to boolean ones. Hence, you
should consider removing this test.
追加で調べる
code:ruby
it { is_expected.to allow_value(true).for(:active) }
it { is_expected.to allow_value(false).for(:active) }
解決