2014-01-16 4 views
1

Я хочу иметь DateTimes с недействительными днями месяца для проверки. Я использую Mongoid 4alpha2 с Rails 4, и на моей модели у меня естьМонгоид/Мопед недействительный день месяца сбережения

field :date_of_birth, type: DateTime

Когда я регулярно «создать» из контроллера для date_of_birth с «1988/02/30», то модель будет сохранена с датой_обытия «1988/03/1» вместо получения ошибки DateInvalid, например, регулярной DateTime.new (1988,2,30) будет в консоли rails. Я не уверен, что мопед или монгод обходят проверки Rails в DateTime, кто-нибудь еще столкнулся с этим?

Вот рельсы войти

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

ответ

1

Похоже, что Mongoid оставляет дату разбора до MongoDB. Проверьте это в MongoDB оболочки:

> new Date('1988/02/30') 
ISODate("1988-03-01T08:00:00Z") 

Это вполне приемлемое поведение для JavaScript's Date constructor:

Примечание: Если дата называется как конструктор с более чем одним аргументом, если значения больше логического диапазона (например, 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 високосный год, февраль и 30 дней в 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 

так, что не помогает.

Вы можете сообщить об ошибке и посмотреть, что думают об этом монгольские люди. В то же время, если вам нужно строже синтаксический, вы можете сделать это самостоятельно:

field :date_of_birth, :type => Date 

def date_of_birth=(date) 
    super(Date.parse(date)) 
end 

Тогда вы получите свое исключение, когда вы говорите Model.create(:date_of_birth => '1988/02/30').

Смежные вопросы