我正在尝试按照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?
答案 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
方法未返回布尔值。或者更确切地说,它永远不会返回错误,因此允许通过。