WedX - журнал о программировании и компьютерных науках

Rails: хранить все строки проверки ActiveRecord в отдельном файле?

ОБНОВЛЕНИЕ (4 декабря 2010 г.):

Я понял, что каждая строка validates на самом деле является вызовом метода (очевидно), поэтому требовать их таким образом было не совсем так, как я ожидал.

Это работает, но я не уверен, что это правильно (полностью определите имя класса Auction):

class Auction::Validations
  Auction.validates :status, :presence => true,
                     :inclusion => { :in => [
                        Auction::CREATING,
                        Auction::OPEN,
                        Auction::PENDING,
                        Auction::CANCELLED,
                        Auction::SUSPENDED,
                        Auction::EXPIRED,
                        Auction::CLOSING_COMPLETED,
                        Auction::CLOSING_WON,
                        Auction::COMPLETED,
                        Auction::WON,
                        Auction::NEGOTIATING,
                        Auction::IN_ESCROW
                     ] }
  Auction.validates :user,   :presence => true
  Auction.validates :url,    :presence => true,
                     # FIXME: Move this to a URLValidator and do :url => true
                     :format => /^https?:\/\/[a-z0-9-]+(\.[a-z0-9-])*\.[a-z0-9]+\/.*/i
  Auction.validates :title,  :presence => true,
                     :length => { :maximum => 255 }
  Auction.validates :description,  :presence => true
  Auction.validates :reserve, :numericality => { :greater_than_or_equal_to => :minimum_bid }
end

Когда это требуется (require 'auction/validations) в классе Auction, он поступает правильно.

Оригинальный вопрос следует:

Пара моих модельных классов немного загромождена всеми этими вызовами «проверки», поэтому я подумал, что смогу переместить их в отдельный класс и «требовать» этого, но это, похоже, не работает.

class Auction < ActiveRecord::Base
  require 'auction/validations'
  ...

class Auction::Validations
  include ActiveModel::Validations

  validates :status, :presence => true,
                     :inclusion => { :in => [
                        ... snip ...
                     ] }
  validates :user,   :presence => true
  validates :url,    :presence => true,
                     # FIXME: Move this to a URLValidator
                     :format => /^https?:\/\/[a-z0-9-]+(\.[a-z0-9-])*\.[a-z0-9]+\/.*/i
  validates :title,  :presence => true,
                     :length => { :maximum => 255 }
  validates :description,  :presence => true
  validates :reserve, :numericality => { :greater_than_or_equal_to => :minimum_bid }

  validates_each :status, :on => :update do |auction, status_attr, value|
    if auction.state_machine.current_state != value
      # FIXME: Raise an Exception instead; this is a developer error, not a user error
      auction.errors.add status_attr, "Status cannot be changed directly"
    end
  end
end

Это не ошибка, но validates_each вообще не выполняет блок (проверено добавлением puts "here"), и проверка числового значения больше не работает.

Когда тело этого класса слепо скопировано обратно в класс Auction, все снова работает.

Я неправильно понимаю, что «требуется» делать с этими проверками?

РЕДАКТИРОВАТЬ:

На самом деле ни одна проверка не работает. Не только эти двое. Хм.



Ответы:


1

Я не уверен, что это правильно, но это как-то работает для меня:

module MyValidations
  module User
    def self.included(base)
      base.validates_presence_of :firstname
    end
  end end

Тогда вы можете позвонить

User.class_eval do
  include MyValidations::User
end

Надеюсь, это поможет.

12.01.2011

2

Ставить в конце Auction::Validations:

Auction.send :extend, Auction::Validations

и в конце Аукциона поставьте требуемую строку.

04.12.2010
  • Спасибо. К сожалению, это, похоже, тоже не сработало. Должно быть, я делаю что-то не так. Если бы кто-то мог опубликовать действительно короткий пример кода модели (подойдет только одно поле) и отдельный класс, содержащий все проверки, было бы здорово. В конце концов я просто сдался и признал, что мои классы моделей должны содержать этот беспорядок. 05.12.2010
  • Я думаю, проблема в том, что это не новые методы, которые добавляются, а фактические вызовы методов. 05.12.2010
  • Хорошо, я нашел способ после того, как кое-что озарило меня, когда я делал этот последний комментарий. Вопрос обновлен... 05.12.2010

  • 3

    Почему бы просто не включить свой модуль?

    module Auction::Validations
      extend ActiveSupport::Concern
      def included(base)
      validates :status, :presence => true,
                         :inclusion => { :in => [
                            ... snip ...
                         ] }
      validates :user,   :presence => true
      validates :url,    :presence => true,
                         # FIXME: Move this to a URLValidator
                         :format => /^https?:\/\/[a-z0-9-]+(\.[a-z0-9-])*\.[a-z0-9]+\/.*/i
      validates :title,  :presence => true,
                         :length => { :maximum => 255 }
      validates :description,  :presence => true
      validates :reserve, :numericality => { :greater_than_or_equal_to => :minimum_bid }
    
      validates_each :status, :on => :update do |auction, status_attr, value|
        if auction.state_machine.current_state != value
          # FIXME: Raise an Exception instead; this is a developer error, not a user error
          auction.errors.add status_attr, "Status cannot be changed directly"
        end
      end
      end
    end
    
    19.10.2010
  • Хммм, такого я еще не видел. Очень новое как для ruby, так и для Rails, спасибо. 19.10.2010
  • Однако, похоже, это не работает. Я получаю те же результаты. При дальнейшем тестировании я обнаружил, что на самом деле ни один код внутри этого требуемого класса не работает должным образом. Как я могу принести его в свой класс аукциона? 19.10.2010

  • 4

    В Rails 4 это легко. Используйте проблемы модели.

    # put this into: app/models/concerns/auction/validations.rb
    class Auction
      module Validations
        extend ActiveSupport::Concern
    
        included do
          validates :status, presence: true
        end
      end
    end
    
    class Auction
      include Validations
    
      # other model code...
    end
    
    13.12.2014
    Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]