#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 Да.