Rails: Хранить все ActiveRecord "проверяет" строки в отдельном файле? - PullRequest
4 голосов
/ 19 октября 2010

ОБНОВЛЕНИЕ (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"), а проверка чисел больше не работает.

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

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

EDIT:

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

Ответы [ 4 ]

2 голосов
/ 12 января 2011

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

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

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

User.class_eval do
  include MyValidations::User
end

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

1 голос
/ 04 декабря 2010

Положите в конце аукциона :: Валидации:

Auction.send :extend, Auction::Validations

и в конце аукциона ставят ту, которая требует строки.

0 голосов
/ 13 декабря 2014

В 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
0 голосов
/ 19 октября 2010

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...