Проблема с проверкой с использованием нескольких объектов Proc

#ruby-on-rails #ruby #proc

#ruby-on-rails #ruby #proc

Вопрос:

У меня есть проверка Proc и проблема с ней

 validates :subcategory, presence: true, 
if: Proc.new {|product| product.detail.blank?} amp;amp; Proc.new { |product|  product.category.id != 16 }
 

Моя проблема в том, что когда у меня true во втором процессе срабатывает моя проверка.

Почему это так? Не должно ли оно возвращаться false , потому false amp;amp; true=>false что?

Ответ №1:

Я думаю, вам было бы лучше использовать один объект proc:

 validates :subcategory,
  presence: true,
  if: Proc.new { |product| product.detail.blank? amp;amp; product.category.id != 16 }
 

Комментарии:

1. Не product.category_id было бы лучше, он не взорвется, если не будет категории, и не нужно будет загружать категорию из базы данных.

2. @j-dexx это действительно было бы, я просто не хотел так сильно изменять код OP 🙂

Ответ №2:

Другие прокомментировали лучшие способы реализации того, что вы хотите. Я просто укажу на возникшее у вас недоразумение.

он должен вернуться false , потому что false amp;amp; true => false

Нет. На самом деле, это Proc amp;amp; Proc => Proc ( proc1 amp;amp; proc2 => proc2 ) . Итак, ваш первый proc игнорируется из-за того, как amp;amp; работает operator (это происходит во время загрузки класса) и никогда не вызывается, даже один раз.

Комментарии:

1. и это было бы реальным ответом на вопрос

2. @sergio-tulentsev Не могли бы вы объяснить, как это игнорируется class loading time ?

3. @Dinesh: это выражение ( Proc amp;amp; Proc ) вычисляется при загрузке файла с этим классом. Поскольку это часть validates call , которая является выражением уровня класса. И да, это означает, что validates он никогда не вызывается снова (поскольку класс уже загружен) ( я игнорирую перезагрузку класса rails в режиме разработки как неуместную ).

Ответ №3:

Я рекомендую использовать метод в:if .

 validates :subcategory, presence: true, if: :my_cond?

def my_cond?
  detail.blank? amp;amp; category.id != 16
end 
 

Это делает ваш код более чистым. если вы найдете действительно хорошее имя для метода my_cond? , ваш код будет более читаемым.

Комментарии:

1. @AndreyDeineko Да.