ruby on rails-Mongoid Date(DateTime)字段未正确解析以存储到数据库中



我已经有这个问题好几天了,找不到任何解决方案。我似乎无法更改Mongoid文档中字段的Date(&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)这更像是日期时区问题。

如有任何帮助和信息,我们将不胜感激。

谢谢。

如果属性定义为date,则需要一个有效的date对象。您应该负责解析值并指定日期。

p = Project.new
p.deadline = Time.Time.strptime("20/10/2011", "%d/%m/%Y")

实际上,我通过元编程重新定义日期字段的setter方法,成功地半自动地完成了这项工作

    #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

convert_dates将在初始化方法中调用(我使用的是自定义类工厂)

因为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"

这样解决:

  # 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

相关内容

最新更新