Rails 3 проверяет включение при использовании find (как обработать или лямбда)

У меня есть проект, в котором есть таблица CURRENCY и COUNTRY. Для модели PRICE требуется действительная валюта и код страны, поэтому у меня есть следующая проверка:

validates :currency_code, :presence => true, :inclusion => { :in => Currency.all_codes }
validates :country_code, :presence => true, :inclusion => { :in => Country.all_codes }

Метод all_codes возвращает массив только кодов валюты или страны. Это работает нормально, пока в таблицу не добавлены коды.

Как бы вы написали это так, чтобы результат Currency.all_codes был либо Proc, либо внутри лямбды? Я попробовал Proc.new { Currency.all_codes } -- но потом получил ошибку, на включение которой объект не отвечает?


person Nicholas C    schedule 17.02.2011    source источник
comment
Какой текущий код вы используете для all_codes?   -  person Dogbert    schedule 18.02.2011
comment
def self.all_codes all.collect(&:CURRENCY_CODE) конец   -  person Nicholas C    schedule 18.02.2011


Ответы (2)


Примечание. Этот ответ верен для старых версий Rails, но для Rails 3.1 и выше процессы принимаются.

Он не должен принимать Procs. Вы можете использовать собственный метод проверки, чтобы сделать то же самое:

validate :currency_code_exists

def currency_code_exists
    errors.add(:base, "Currency code must exist") unless Currency.all_codes.include?(self.currency_code)
end
person ctcherry    schedule 17.02.2011
comment
Обратите внимание, что в rails ›= 3.1 вы можете использовать lambda или proc, как в непринятом ответе ниже. apidock.com/rails/v3.1.0/ActiveModel/Validations/HelperMethods/ - person Mik; 11.07.2012

Просто используйте процедуру, например:

validates :currency_code,
          :presence => true,
          :inclusion => { :in => proc { Currency.all_codes } }
validates :country_code,
          :presence => true,
          :inclusion => { :in => proc { Country.all_codes } }

Стоит отметить для всех, кто может наткнуться на это, что процедура также имеет запись, доступную в качестве параметра. Итак, вы можете сделать что-то вроде этого:

validates :currency_code,
          :presence => true,
          :inclusion => { :in => proc { |record| record.all_codes } }

def all_codes
  ['some', 'dynamic', 'result', 'based', 'upon', 'the', 'record']
end
person Matt Huggins    schedule 01.04.2012
comment
lambda также имеет доступ к записи? - person ocodo; 23.02.2013
comment
Да, лямбда — это тип процедуры (см. здесь), поэтому запись также будет доступна. - person Matt Huggins; 23.02.2013
comment
Доступ к записи в качестве параметра процедуры решил проблему, с которой я столкнулся. Использование Rolify в классе Article, относящемся к классу Column с авторами и редакторами: validates :column, inclusion: { in: proc{ |article| Column.with_role([:author, :editor], article.user) } } - person jbhannah; 26.02.2013