Rails:将所有ActiveRecord“验证”行保存在单独的文件中?

时间:2010-10-19 09:46:55

标签: ruby-on-rails validation ruby-on-rails-3 module

更新(2010年12月4日):

我意识到每个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类中,一切都有效。

我是否误解了“要求”对这些验证的影响?

编辑:

事实上,没有任何验证有效。不只是那两个。嗯。

4 个答案:

答案 0 :(得分:2)

我不确定这是否正确,但它对我有用:

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 :(得分:1)

结束拍卖::验证:

Auction.send :extend, Auction::Validations

并在拍卖结束时提出要求行。

答案 2 :(得分:0)

为什么不包含您的模块?

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

答案 3 :(得分:0)

在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