Rails 가 제공하는 Model단의 validation 기능과 사용자 페이지(View)에 메세지를 보여주는 기능은 무척 유용하다. 만약, 가격 필드에 문자값을 넣으면 validates_numericality_of 메서드를 이용하여 검증하면 다음과 같은 메세지를 뿌려준다.
class Order < ActiveRecord::Base validates_numericality_of :price end--------------------------------------------------------
위 메세지를 한글화 하려면 옵션을 주면 다음과 같이 보이게 할수 있다.
class Order < ActiveRecord::Base validates_numericality_of :price, :message => "항목은 숫자만 입력가능 합니다." end "Price 항목은 숫자만 입력가능 합니다."
문제는 저 Price 이다. 이는 속성의 이름이 default 로 문장의 맨앞에 나와있으며, 이를 바꿀 방법이없다. 그렇기에 아쉽지만 좀더 사용자 친화적인 메세지로 바꾸려면 validates_numericality_of 메서드를 포기하고 직접 만드는 수밖에 없다. 다음처럼 말이다.
class Order < ActiveRecord::Base validate :price_must_be_a_number protected def price_must_be_a_number begin Kernel.Float(price) rescue ArgumentError, TypeError errors.add('price', '항목은 숫자만 입력해주세요.') end end end
Kernel.Float 는 값이 float 타입인지를 판별하는 여러 방법중 하나이다. 이 방법이 아닌 다르게 체크해도 상관없다. 한데 문제가 있다. 사용자가 숫자가 아닌 문자열을 입력했을 때, price_must_be_a_number 메서드의 price 속성에 떨어지는값이 0.0인것이다 ! Rails 자체적으로 숫자입력이 필요한곳에 문자입력을 했을때 자동으로 0.0으로바꾸는것이다. 그렇기에 사용자가 문자를 입력해도 위의 validation이 통과되버리게된다.
해결방법을 찾아 며칠 전전긍긍한 끝에 Rails API 에서 해답을 얻을 수 있었다 !
http://api.rubyonrails.org/classes/ActiveRecord/Base.html 에 문제를 푸는 열쇠가 담겨있다. 다음과 같은 내용이 있다.
_before_type_cast 를 통해, 케스팅되기 전의 값을 알수 있는 것이다! 이제 다음과 같이 validation 체크가 가능하다.
validate :price_must_be_a_number protected def price_must_be_a_number begin Kernel.Float(price_before_type_cast) rescue ArgumentError, TypeError errors.add('price', '가격항목에는 숫자만 입력해주세요.') end end "Price 가격항목에는 숫자만 입력해주세요."
자, 이제 한글 validation 메세지를 보여주는 마지막 단계이다. errors.add 함수에는 세개의 인자값을 받는데, 다음처럼 마지막 인자인 option 설정을 통해 메세지에서 Price 부분을 제거할 수 있다.
validate :price_must_be_a_number protected def price_must_be_a_number begin Kernel.Float(price_before_type_cast) rescue ArgumentError, TypeError errors.add('price', '가격항목에는 숫자만 입력해주세요.', {:attribute => '' }) end end "가격항목에는 숫자만 입력해주세요."
위의 방식을 응용하면 모든 입력폼에 관한 한글 validation 메세지를 사용자들에게 제공해줄 수 있게 된다. :)
라벨: Model, Ruby on Rails, Validation