Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoid Date (DateTime) field not parsing correctly to store into database

I have been having this issue for days and couldn't find any solution for this. It seems that I can't change the format of Date (& DateTime) of a field in a Mongoid Document

class Project
  include Mongoid::Document

  field :deadline, :type => Date
end

Then I can assign Date like this:

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

But I can't assign in other formats:

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

The thing is I tried changing the default format of Mongoid Date in several ways including

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

which does work to display the data in that format but not to store the data in the format. I tried with localisation file as follow:

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

It doesn't work either. It's probably me not know how to get it right but it could be an issue with Mongoid.

I am using:

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

I am aware of this (https://github.com/mongoid/mongoid/issues/53) which is more a Date timezone issue.

Any help and info with be greatly appreciated.

Thanks.

like image 309
Phyo Wai Win Avatar asked Dec 19 '25 22:12

Phyo Wai Win


2 Answers

If the attribute is defined as date, it expects a valid Date object. You should be responsible for parsing the value and assigning a date.

p = Project.new
p.deadline = Time.Time.strptime("20/10/2011", "%d/%m/%Y")
like image 76
Simone Carletti Avatar answered Dec 22 '25 13:12

Simone Carletti


I've actually managed to do this semi automatically, by redefining the setter methods for the Date fields via meta-programming

    #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

The convert_dates would be called in your initialize method (I am using a custom class factory)

like image 38
Piotr Kaluza Avatar answered Dec 22 '25 13:12

Piotr Kaluza



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!