왜인가 boolean 의 validates ~ presence 가 언제나 에러가 된다

Active Record Validation



Ruby on Rails의 Active Record에 있는 validates는 편리하죠.
class Person < ActiveRecord::Base
  validates :name, presence: true
end

라고 하는 모델이 있을 때에 name 에 값이 들어가 있는지를 확인해 주고, 없는 경우에는 에러라든지 확실히 설정해 준다.
편리

값이 있지만 유효성 검사가 false ???



다만, boolean 의 필드로 이것을 사용했을 때에 조금 집계했습니다.
class Person < ActiveRecord::Base
  validates :name, presence: true
  validates :has_glasses, presence: true
end

라는 모델이 있다면,
irb> person = Person.new(name: "Daisuke", has_glasses: false)
 => #<Person id: nil, name: "Daisuke", has_glasses: false>
irb> person.has_glasses
 => false
irb> person.valid?
=> false

false 의 값이 has_glasses 로 설정되어 있어야 하지만 유효성 검사를 통과하지 못합니다.

? ? ?

그래서, 조금 조사해 보면, 이것, 실은 presence 의 동작이 (나 개인의 의견으로서) 직관적이지 않은 것이 원인이었습니다.
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

되어 오류로 인식됩니다!

한층 더 파헤치면(자) , 아무래도 , 이 blank? 메소드, Rails 의 라이브러리의 하나인 ActiveSupportObject 클래스에 추가되고 있는 것 같습니다.

Ruby on Rails API
def blank?
  respond_to?(:empty?) ? !!empty? : !self
end
booleanempty? 메서드가 없으므로 !self 의 결과, 즉 true 가 반환됩니다.

올바른 Boolean 필드를 확인하는 방법



Booelan의 유효성을 검사하려면 ActiveModel::Validations::InclusionValidator ( validates
validates :has_glasses, inclusion: [true, false]

하는 것이 좋다.

참고 링크



A Developer with a Pencil

좋은 웹페이지 즐겨찾기