1

В настоящее время я работаю над приложением для отслеживания диеты. У меня есть модель FoodEntry, где каждый экземпляр ссылается на один food из другой таблицы, а также ссылается на единицу measurement из еще одной таблицы.Проверка соответствующих моделей в Rails

class FoodEntry < ActiveRecord::Base 
    belongs_to :food 
    belongs_to :measurement 
    validates :food, presence: { message: 'must exist' } 
    ... 
end 

Это работает хорошо, но дело в том, что каждая запись в таблице measurements установлен (потому что я работаю с внешними данными), которые будут связаны с определенным food, т.е. измерение относится к пище и пища имеет много измерений:

class Food < ActiveRecord::Base 
    has_many :measurements 
    ... 
end 

class Measurement < ActiveRecord::Base 
    belongs_to :food 
    ... 
end 

Мой вопрос, что такое правильный способ проверить, что конкретный measurement я ссылка в food_entry также является одним из его food.measurements?

В настоящее время в моей FoodEntry модели я делаю это:

validate :measurement_must_be_associated 

def measurement_must_be_associated 
    unless food.measurements.include? measure 
    errors.add(:measurement, 'is not associated with that food') 
    end 
end 

Этот обычай проверка работает, но я не уверен, что это самый чистый способ сделать это.

Я попытался сделать это вместо:

validates :measurement, inclusion: { in: food.measurements } 

, но это дает мне ошибку при вызове FoodEntry.new(food_id: 1, measurement_id: 1) в консоли рельсы (фактические id s не имеют значения):

NameError: undefined local variable or method `food' for FoodEntry (no database connection):Class 

Использование in: self.food.measurements в валидация не отличалась. Помогите?

ответ

3

Try:

validates :measurement, inclusion: { in: ->(record) { record.food.measurements } } 

validates является метод, определенный на классе, и оценивается при объявлении класса. Обычно, когда значения включения известны до запуска программы (и являются статическими), достаточное значение прохождения - валидатор (который создается при вызове validates) просто сохраняет переданный объект и использует его при проверке.

В вашем случае значения включения неизвестны в момент создания валидатора (и они также зависят от проверяющего объекта). Следовательно, вам нужно передать лямбда, поэтому валидатор может использовать его для получения значений включения во время выполнения.

Обратите внимание, что объект-валидатор прикреплен к классу, а не к определенному экземпляру, поэтому лямбда должна иметь параметр записи.

Смежные вопросы