Ruby on rails 如何改变RubyonRails解析两位数年份输入的方式

Ruby on rails 如何改变RubyonRails解析两位数年份输入的方式,ruby-on-rails,ruby,datetime,activerecord,Ruby On Rails,Ruby,Datetime,Activerecord,我有一个表单,它接受格式为(m/d/yy)的文本字段中的日期 当保存日期时(使用ActiveRecord),它会被解析为“0014”年,而不是“2014”。在这个字段中,我希望它总是将世纪猜测为2000年 控制台中有一个[失败]测试: 2.0.0-p247 :021 > g.update_attributes(:date_completed => "3/4/14") (0.3ms) BEGIN SQL (0.7ms) UPDATE `goals` SET `date_c

我有一个表单,它接受格式为(m/d/yy)的文本字段中的日期

当保存日期时(使用ActiveRecord),它会被解析为“0014”年,而不是“2014”。在这个字段中,我希望它总是将世纪猜测为2000年

控制台中有一个[失败]测试:

2.0.0-p247 :021 > g.update_attributes(:date_completed => "3/4/14")
   (0.3ms)  BEGIN
  SQL (0.7ms)  UPDATE `goals` SET `date_completed` = '0014-03-04', `updated_at` = '2014-06-30 21:36:06' WHERE `goal_tracker_goals`.`id` = 10
   (1.7ms)  COMMIT
 => true 
2.0.0-p247 :023 > g.date_completed
 => Sun, 04 Mar 0014 
我假设有一个ActiveRecord方法要覆盖某个地方,或者有一个配置值要设置

谢谢

试试看:

g.date_completed=Date.parse("3/4/14")
要绕过默认区域设置,请尝试:[更新问题后,这是正确答案]


大胆的解决方案,但它是唯一涵盖所有情况的解决方案。在应用程序中的任何位置,当设置了日期类型的属性时,它将在写入之前通过
date.parse()
发送该属性

# initializers/active_record_extension_parse_date_writer.rb

module ActiveRecordExtensionParseDateWriter

  private

  def write_attribute(attr_name, value)
    if self.class.column_types.fetch(attr_name.to_s).type == :date
      d = (Date.parse(value.to_s)) rescue nil
      super(attr_name, d)
    else
      super
    end
  end

end

# include the extension
ActiveRecord::Base.send(:include, ActiveRecordExtensionParseDateWriter)

谢谢这在控制台中起作用,但我更关心的是接受表单提交的情况,其中日期字段来自(m/d/yy)格式的文本输入。我已经更新了这个问题。然后你可以试试我的第二个建议,它已经准备好了。只需使用传入变量更改“3/4/14”。在第二个建议中,字符串被解析为m/d/y(2位数字的年份)。您自己解析日期字符串是否有问题?没有人强迫你盲目地将
params
中的内容直接转储到你的模型中,你的控制器被允许处理数据格式转换(我甚至可以说这是控制器的工作,Rails试图将所有逻辑推到模型中是错误的)。这只是为了让它保持干燥。整个现场有许多日期输入,m/d/yy是首选格式。我只是想知道是否有一种覆盖或配置值的方法可以告诉Rails将两位数的年份解释为本世纪。我知道,这是一个不太可能实现的目标。如果这些值的命名一致,那么您可以将before过滤器破解到
ApplicationController
,如果不是,那么您可以在每个控制器的基础上添加自己的宏来预处理事情。
# initializers/active_record_extension_parse_date_writer.rb

module ActiveRecordExtensionParseDateWriter

  private

  def write_attribute(attr_name, value)
    if self.class.column_types.fetch(attr_name.to_s).type == :date
      d = (Date.parse(value.to_s)) rescue nil
      super(attr_name, d)
    else
      super
    end
  end

end

# include the extension
ActiveRecord::Base.send(:include, ActiveRecordExtensionParseDateWriter)