【问题标题】:How to implement custom date validation in Ruby on Rails如何在 Ruby on Rails 中实现自定义日期验证
【发布时间】:2016-03-11 15:25:10
【问题描述】:

我正在尝试按照 Rails Guides 中的示例来实现自定义验证,但我似乎无法验证日期。

这里是迁移:

class CreateSetLists < ActiveRecord::Migration
  def change
    create_table :set_lists do |t|
      t.date :show_date
      t.string :show_name

      t.timestamps
    end
  end

结束

这是模型:

class SetList < ActiveRecord::Base
  validates :show_date, :show_name, presence: true
  validate :must_have_valid_future_date

  private

  def must_have_valid_future_date
    if show_date.present?
        unless show_date.is_a?(Date)
            errors.add(:show_date, "must be a valid date")
        end

        if show_date < Date.today
            errors.add(:show_date, "can't be in the past")
        end
    end
  end

end

当我尝试通过提交无效日期来对此进行测试时,我的对象的错误哈希显示一条消息,就好像从未设置过日期一样。如果我删除“存在”验证,那么当我提交一个无效的日期时,该对象只会以 nil 保存该日期。

验证我是否有遗漏的有效日期有什么特别之处吗?

更新(2015-12-07 上午 11:45):

我注意到控制台中出现了这种情况:

irb(main):044:0> msl=SetList.new
=> #<SetList id: nil, show_name: nil, show_date: nil, created_at: nil, updated_at: nil>
irb(main):045:0> msl.show_date="invalid"
=> "invalid"
irb(main):046:0> msl.show_date
=> nil

看起来 Rails 不允许我验证我有一个有效的日期。它只是丢弃无效日期并将字段设置为 nil。

这是否是该属性的列类型的某些属性为日期类型?我是否可以依赖这种行为,从而消除验证我是否有有效日期的需要(因为 Rails 会自动丢弃无效日期)?

更新(2015-12-07 晚上 8:04):

这个问题似乎暗示我可以依靠 Rails 丢弃无效日期,而无需在我的模型中进行任何验证:

rails 3.1 date validation - is acts_like_date? enough or even necessary?

【问题讨论】:

    标签: ruby-on-rails validation date


    【解决方案1】:

    似乎没有必要对日期属性执行验证以确保条目是有效日期。如果提交的值不是有效日期,则 rails 会在调用任何验证方法之前将其丢弃并将属性设置为 nil。

    【讨论】:

      【解决方案2】:

      如果您拆分逻辑,有时更容易调试边缘情况。也许是这个方向的东西:

      def must_have_valid_future_date
        valid_date and future_date
      end
      
      def valid_date
        errors.add(:show_date, "must be a valid date") unless show_date.is_a?(Date)
      end
      
      def future_date
        errors.add(:show_date, "can't be in the past") if show_date < Date.today
      end
      

      如果我删除“存在”验证,那么当我提交一个无效的日期时,该对象只会以 nil 保存该日期。

      这是因为您的 must_have_valid_future_date 方法没有返回布尔值。或者更确切地说,它从不返回 false,因此 nil 允许通过。

      ActiveModel::Validations

      【讨论】:

      • 我不相信我的验证方法需要返回 false(或任何东西)。来自 ActiveModel::Validations 文档:“请注意,验证方法的返回值不相关。不可能停止验证回调链。”
      猜你喜欢
      • 2012-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      • 2011-04-11
      相关资源
      最近更新 更多