我希望将DateTimes与当月的无效天数进行验证。我正在使用Mongoid 4alpha2和Rails 4,在我的模型上我有一个
field :date_of_birth, type: DateTime
当我使用“1988/02/30”从控制器为date_of_birth定期“创建”时,模型以date_of_birth“1988/03/1”保存,而不是获得DateInvalid错误,如常规DateTime.new(1988,2,30)将在rails控制台中。我不确定轻便摩托车或mongoid是否绕过了DateTime上的Rails验证,有没有其他人遇到过这个问题?
这是rails log
Started POST "/drivers" for 127.0.0.1 at 2014-01-16 10:42:40 -0500
Processing by DriversController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"LiKx1ZToNVtNL9FAEgyLNNWW7mABy2BPKPwVVcTtXKk=", "driver"=>{"field_worker_name"=>"Field Worker", "hack_number"=>"38924", "first_name"=>"test", "middle_initial"=>"", "last_name"=>"testing", "date_of_birth"=>"1988/02/30", "gender"=>"", "nationality"=>"", "language"=>"", "street"=>"something", "apartment_number"=>"", "city"=>"something", "state"=>"NY", "zip_code"=>"02398", "cell_phone"=>"", "other_phone"=>"", "email"=>"", "dmv_number"=>"", "state_of_residence"=>"", "has_health_insurance"=>"false", "health_plan"=>"", "date_of_recertification"=>""}, "commit"=>"Add Driver"}
MOPED: 127.0.0.1:27017 COMMAND database=admin command={:ismaster=>1} runtime: 0.5280ms
MOPED: 127.0.0.1:27017 QUERY database=healthfund_development collection=users selector={"$query"=>{"_id"=>BSON::ObjectId('52d59524544b38160c000000')}, "$orderby"=>{:_id=>1}} flags=[] limit=-1 skip=0 batch_size=nil fields=nil runtime: 0.4150ms
MOPED: 127.0.0.1:27017 QUERY database=healthfund_development collection=drivers selector={"hack_number"=>38924} flags=[] limit=-1 skip=0 batch_size=nil fields={:_id=>1} runtime: 1.1000ms
MOPED: 127.0.0.1:27017 INSERT database=healthfund_development collection=drivers documents=[{"field_worker_name"=>"Field Worker", "hack_number"=>38924, "first_name"=>"test", "middle_initial"=>"", "last_name"=>"testing", "date_of_birth"=>1988-03-01 00:00:00 UTC, "gender"=>"", "street"=>"something", "apartment_number"=>"", "city"=>"something", "state"=>"NY", "zip_code"=>"02398", "cell_phone"=>"", "other_phone"=>"", "email"=>"", "nationality"=>"", "language"=>"", "dmv_number"=>"", "state_of_residence"=>"", "has_health_insurance"=>false, "health_plan"=>"", "date_of_recertification"=>nil, "_id"=>38924, "updated_at"=>2014-01-16 15:42:40 UTC, "created_at"=>2014-01-16 15:42:40 UTC}] flags=[]
COMMAND database=healthfund_development command={:getlasterror=>1, :w=>1} runtime: 3.4590ms
Redirected to http://localhost:3000/drivers/38924
Completed 302 Found in 17ms
答案 0 :(得分:1)
看起来Mongoid正在将解析日期留给MongoDB。在MongoDB shell中检查它:
> new Date('1988/02/30')
ISODate("1988-03-01T08:00:00Z")
这是JavaScript's Date
constructor完全可以接受的行为:
注意:如果将Date作为具有多个参数的构造函数调用,如果值大于其逻辑范围(例如,13为月值或70为分钟值),则将调整相邻值。例如。
new Date(2013,13,1)
相当于new Date(2014,1,1)
,都为2014-01-01
创建了一个日期。同样,对于其他值:new Date(2013,2,1,0,70)
相当于new Date(2013,2,1,1,10)
,它们都为2013-02-01T01:10:00
创建日期。
就MongoDB而言,1988/02/30
是1988年加2个月加30天,自1988年起是闰年,2月加3月1日30天。
无论如何,您应该使用:type => Date
来表示出生日期。当然,Date
具有相同的“像JavaScript一样对待”行为:
class M
include Mongoid::Document
field :d, :type => Date
end
m = M.create(:d => '1988/02/30')
m.d
# Tue, 01 Mar 1988
所以这没什么用。
你可以报告一个错误,看看Mongoid人对此的看法。同时,如果您需要更严格的解析,您可以自己完成:
field :date_of_birth, :type => Date
def date_of_birth=(date)
super(Date.parse(date))
end
然后,当您说Model.create(:date_of_birth => '1988/02/30')
时,您会收到异常。