Условная проверка для сериализованного массива

#ruby-on-rails #ruby #validation #activerecord

#ruby-on-rails #ruby #проверка #activerecord

Вопрос:

Как я могу создать проверку, в которой committed присутствие должно быть истинным, только если категория задачи равна habit ?

 class Challenge < ActiveRecord::Base
  CATEGORY = ['goal', 'habit']
  serialize :committed, Array
  validates :committed, presence: true, if: :habit # I also tried with 'habit' amp; 'Habit'
end
  

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

1. Где у вас хранится категория? Это столбец или находится в другой таблице?

2. Это столбец в таблице задач, t.string "category" @Nobita

Ответ №1:

Поскольку ваша категория вызывается 'habit' (обратите внимание, это не 'Habit' так), проверка будет выглядеть следующим образом:

 validates :committed, presence: true, if: ->(c) { c.category == 'habit' }
  

В качестве примечания: я не думаю, что ваши области будут работать, если у вас нет столбца, вызываемого categories в вашей challenges таблице.
Таким образом, если вы намеревались выбрать задачи, которые имеют категорию 'habit' , область будет выглядеть следующим образом:

 scope :habit, -> { where(category: 'habit') }
  

Редактировать

Согласно обсуждению в комментариях, если вы хотите committed быть nil вместо [""] , когда ничего нет, добавьте пользовательскую проверку:

 validate :committed_content

private

def committed_content
  self.committed = nil if committed.empty? || committed.all?(amp;:blank?)
  true
end
  

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

1. Хороший момент. Да, я уберу это, так как думал, что это часть этого, но я думаю, что нет. Однако я получаю сообщение об ошибке, syntax error, unexpected '.' ... true, if: ->(c) { c.categoryamp;.== 'habit' }

2. @AnthonyGalli.com О, может быть, у вас есть Ruby <= 2.3. Попробуйте это: validates :committed, presence: true, if: ->(c) { c.category == 'habit' }

3. Проводил тестирование, и я вижу проблему. У меня есть это в модели serialize :committed, Array , которую я не включил в вопрос:/ и поэтому, даже если ничего :committed нет, я вижу, что оно передается в базу данных как committed: [""] вместо nil . Вы знаете, что я могу заставить проверку работать для этого?

4. @AnthonyGalli.com итак, вы не хотите иметь [""] его в базе данных и хотите предотвратить его сохранение? Если да, вам следует добавить проверку содержимого. позвольте мне отредактировать вопрос, как только вы подтвердите

5. Да, либо это … или сделайте его nil пустым. Любой способ работает, если вы знаете, как это сделать. Спасибо, добрый сэр!

Ответ №2:

 validates :committed, presence: true, :if => lambda { |c| c.category == 'Habit' } 
  

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

1. Это выдает ошибку: syntax error, unexpected => ...committed, presence: true, if => lambda { |c| c.categories ==... ... ^

2. @AnthonyGalli.com проверьте сейчас, является ли это символом, я обновил ответ

3. Спасибо, но теперь я получаю uninitialized constant ActiveSupport::Callbacks::Callback::Habit

4. @AnthonyGalli.com Опубликуйте весь свой вызов.rb

5. Спасибо, что помогли мне сузить проблему. Это было немного сложнее, и Андрей тоже помог разобраться.

Ответ №3:

У вас может быть метод и использовать его следующим образом:

 validates :committed, presence: true, if: :habit?

def habit?
  self.category == 'habit'
end