#ruby-on-rails #ruby-on-rails-3 #validation #activerecord
#ruby-on-rails #ruby-on-rails-3 #проверка #activerecord
Вопрос:
У меня есть эта модель
class User < ActiveRecord::Base
attr_accessible :type, :school_name, :school_grade
validates :type, :inclusion =>{:in =>['1','2']}, :allow_blank => true
validates :school_name, :presence =>{:if => :student?}
validates :school_grade, :numericality =>{:only_integer =>true}, :allow_blank => {:unless => :student?}
def student?
type.to_s == '1'
end
end
Я попробовал следующие шаблоны.
User.create(:type =>'2', :school_name =>nil, :school_grade =>nil)
=> OK. Ошибки не произошло.
User.create(:type =>'1', :school_name =>nil, :school_grade =>1)
=> OK. Произошла ошибка ActiveRecord::RecordInvalid «имя_школы пусто».
User.create(:type =>'1', :school_name =>'foo', :school_grade =>'string is not a number')
=> OK. Произошла ошибка проверки «school_grade не является числом».
User.create(:type =>'1', :school_name =>'foo', :school_grade =>nil)
=> NG. Я ожидаю ошибку «school_grade — это не число», но ошибки не произошло.
Я тоже пробовал этот шаблон, но получил тот же результат.
validates :school_grade, :numericality =>{:only_integer =>true}, :allow_blank => {:if => :not_student?}
def not_student?
type.to_s != '1'
end
Я думаю, проверка: allow_blank всегда активна, но почему? И как это исправить?
Спасибо.
Комментарии:
1. какой тип данных
type
в БД?
Ответ №1:
allow_blank
не принимает Hash
, только логическое значение, поэтому вы не можете написать что-то подобное :allow_blank => {:unless => :student?}
, как вы можете видеть в исходном activemodel-4.1.2/lib/active_model/validator.rb
def validate(record)
attributes.each do |attribute|
value = record.read_attribute_for_validation(attribute)
next if (value.nil? amp;amp; options[:allow_nil]) || (value.blank? amp;amp; options[:allow_blank])
validate_each(record, attribute, value)
end
end
Однако то, чего вы хотите достичь, может быть сделано в двух строках:
class User < ActiveRecord::Base
validates_presence_of :school_grade, :if => :student?
validates :school_grade, :numericality =>{:only_integer =>true}, :allow_blank => true
end
Комментарии:
1. Этот код работает для меня. Но я получил
validates_presence_of is deprecated in Rails
, поэтому я изменил вот так.validates :school_grade, :presence =>true, :if => :student?
Спасибо.2. Хорошо. Но теперь мне любопытно и я беспокоюсь о причине моей настройки в Rails 4.1.2, я не получаю никаких предупреждений об амортизации. Я погуглил и обнаружил, что амортизация для
validates_presence_of
была в Rails 3. Какую версию вы используете?3. Также в текущей версии git я не вижу никакого кода, связанного с амортизацией github.com/rails/rails/blob /…
4. Я использую Rails 3.2.18. Спасибо за вашу информацию. Это стало полезным.
Ответ №2:
Вы хотите, чтобы allow_blank был условным или чтобы проверка всей численности была полной?
Если последнее:
validates :school_grade, :numericality =>{:only_integer =>true}, :allow_blank => true, :unless => :student?
validates :school_grade, :numericality =>{:only_integer =>true}, :allow_blank => false, :if => :student?
Комментарии:
1. Этот код допускает нецелочисленный параметр, когда
student?
естьfalse
. Я хочу отклонить его, но только тогда, когдаstudent?
естьfalse
, хочу разрешитьnil
. Спасибо.2. Я обновил свой ответ. Выполните две проверки для school_grade. Один для случая student, один для случая not student.
3. Последний код работает хорошо. Но у Бенджамина проще, потому что в моем реальном коде есть другие проверки. В любом случае спасибо.