Поле Mongoid Date (DateTime) неправильно анализируется для сохранения в базе данных - PullRequest
3 голосов
/ 27 мая 2011

У меня была эта проблема в течение нескольких дней, и я не мог найти никакого решения для этого.Кажется, что я не могу изменить формат даты (& DateTime) поля в монгоидном документе

class Project
  include Mongoid::Document

  field :deadline, :type => Date
end

Тогда я могу назначить дату следующим образом:

p = Project.new
p.deadline = "20-10-2011"

НоЯ не могу назначить в других форматах:

p.deadline = "20/10/2011"
ArgumentError: invalid date
    from /Users/pww/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/date.rb:956:in `new_by_frags'
    from /Users/pww/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/date.rb:1000:in `parse'
    from /Users/pww/.rvm/gems/ree-1.8.7-2011.03@v3/gems/mongoid-2.0.2/lib/mongoid/extensions/date/conversions.rb:18:in `convert_to_time'
    from /Users/pww/.rvm/gems/ree-1.8.7-2011.03@v3/gems/mongoid-2.0.2/lib/mongoid/extensions/time_conversions.rb:6:in `set'
    from /Users/pww/.rvm/gems/ree-1.8.7-2011.03@v3/gems/mongoid-2.0.2/lib/mongoid/field.rb:109:in `set'
    from /Users/pww/.rvm/gems/ree-1.8.7-2011.03@v3/gems/mongoid-2.0.2/lib/mongoid/attributes.rb:182:in `typed_value_for'
    from /Users/pww/.rvm/gems/ree-1.8.7-2011.03@v3/gems/mongoid-2.0.2/lib/mongoid/attributes.rb:96:in `write_attribute'
    from /Users/pww/.rvm/gems/ree-1.8.7-2011.03@v3/gems/mongoid-2.0.2/lib/mongoid/fields.rb:161:in `deadline='
    from (irb):11

Дело в том, что я попытался изменить формат Mongoid Date по умолчанию несколькими способами, включая

Date::DATE_FORMATS[:default] = "%d/%m/%Y"

, который работает для отображения данныхв этом формате, но не для хранения данных в формате.Я попытался с файлом локализации следующим образом:

date:
    formats:
      default: "%d/%m/%Y"
      short: "%b %d"
      long: "%B %d %Y"

Это тоже не работает.Вероятно, я не знаю, как сделать это правильно, но это может быть проблемой с Mongoid.

Я использую:

Mongoid (2.0.2)
Rails (3.0.6)
ree (1.8.7-2011.03)

Я знаю об этом (https://github.com/mongoid/mongoid/issues/53), что больше относится к часовому поясу даты.

Любая помощь и информация с благодарностью.

Спасибо.

Ответы [ 4 ]

3 голосов
/ 27 мая 2011

Если атрибут определен как дата, он ожидает действительный объект Date.Вы должны нести ответственность за анализ значения и назначение даты.

p = Project.new
p.deadline = Time.Time.strptime("20/10/2011", "%d/%m/%Y")
2 голосов
/ 25 сентября 2012

Мне фактически удалось сделать это полу автоматически, переопределив методы установки для полей Date с помощью метапрограммирования

    #this returns all the Date fields as an array
    def self.date_fields
    self.fields.map {|f,v| f if v.type == Date}.compact

    end


    def self.convert_dates 

    #go through all the fields and define a method for each
    self.date_fields.each  do |f|

    define_method "#{f}=".intern do |arg|

    #if there is a value
    if arg.present?   
    begin
     #try to parse it the normal d/m/Y way
      new_date =Date.parse(arg)

    rescue
      #if it fails attempt the US format. Could add more formats by nesting 
      #rescues
      new_date = DateTime.strptime(arg, '%m/%d/%Y')
    end
      #call super to let Mongoid handle it
    super(new_date)
    end
    end
    end

Преобразование_даты будет вызвано в вашем методе инициализации (я используюфабрика нестандартного класса)

1 голос
/ 24 ноября 2011

потому что field: deadline,: type => Date будет генерировать объект с типом Time, а не типом Date.Вы можете проверить это в консоли rails с p.deadline.is_a? Date, что приведет к FALSE, но p.deadline.is_a? Time сгенерирует true,

проблема, исправленная обновлением вашего mongoid до последней версии

gem 'mongoid', :git => "git://github.com/mongoid/mongoid.git"
0 голосов
/ 27 сентября 2012

Решил это так:

  # our form sends in month, day, year
  def my_date=(*args)
    if args.first.is_a?(String)
      args[0] = Time.strptime(args[0], "%m/%d/%Y")
    end
    super(*args)
  end
...