【问题标题】:Mongoid/Moped invalid day of month getting saved保存 Mongoid/Moped 无效的月份日期
【发布时间】:2014-01-16 15:43:54
【问题描述】:

我想要验证包含无效日期的 DateTimes。我正在使用带有 Rails 4 的 Mongoid 4alpha2,在我的模型上我有一个

field :date_of_birth, type: DateTime

当我从控制器为“1988/02/30”的 date_of_birth 执行常规“创建”时,模型会以“1988/03/1”的 date_of_birth 保存,而不是出现 DateInvalid 错误,例如常规 DateTime.new(1988,2,30) 将在 Rails 控制台中。我不确定 moped 或 mongoid 是否绕过了 DateTime 上的 Rails 验证,还有其他人遇到过这种情况吗?

这是rails日志

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

【问题讨论】:

    标签: mongodb datetime ruby-on-rails-4 mongoid moped


    【解决方案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 月加 30 天,即 3 月 1 日。

    无论如何,您都应该使用: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') 时你会得到你的例外。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多