如何在Ruby on Rails中实现自定义日期验证

时间:2015-12-07 04:41:00

标签: ruby-on-rails validation date

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

以下是迁移:

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

当我尝试通过提交无效日期来测试时,我的对象的错误哈希显示一条消息,就好像日期从未设置过一样。如果我删除&#34;存在&#34;验证,然后当我提交无效日期时,对象只需用nil保存日期。

有没有什么特别的关于验证我有错过的有效日期?

更新(2015-12-07 11:45 am):

我注意到这在控制台中玩耍:

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。

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

更新时间(2015-12-07 8:04 pm):

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

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

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

如果拆分逻辑,有时更容易调试边缘情况。也许是朝着这个方向发展:

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方法未返回布尔值。或者更确切地说,它永远不会返回错误,因此允许通过。

ActiveModel::Validations