Rails 从 6.1 升级到 7.0 后忽略默认日期格式

GoB*_*sto 11 ruby-on-rails date-formatting ruby-on-rails-7

我们的应用程序之前定义了默认日期格式,如下DD/MM/YYYY所示config/application.rb

Date::DATE_FORMATS[:default] = '%d/%m/%Y'
Run Code Online (Sandbox Code Playgroud)

这在 Rails 6.1 中按预期工作,但升级到 Rails 7.0 后,它现在似乎被忽略.to_s

Loading development environment (Rails 7.0.2.2)
3.0.1 :001 > Date::DATE_FORMATS[:default]
 => "%d/%m/%Y" 
3.0.1 :002 > Date.new(2022, 12, 31).to_s
 => "2022-12-31"
3.0.1 :003 > Date.new(2022, 12, 31).to_fs
 => "31/12/2022" 
Run Code Online (Sandbox Code Playgroud)

如何.to_s在 Rails 7.0+ 中实现此行为?

小智 13

请记住,config.active_support.disable_to_s_conversion不会恢复to_s约会的原始功能。您的日期不会达到您配置的默认格式化程序。

我不确定这是否是故意的。

您有两种选择来解决此问题:

  1. 找到您需要以所选格式显示日期的所有位置并添加.to_fs. 这可能是解决此问题的更正确方法。
  2. 或者做我们所做的事情并违背 Rails 开发人员的意愿。添加一个重写.to_s日期方法的初始值设定项,因为要添加到.to_fs代码中的每个日期显示的 9000 多个不同位置对于您现在来说实在是太多了。

./config/initializers/date_format_fix.rb

require "date"

class Date
  def to_s(format = :default)
    if formatter = DATE_FORMATS[format]
      if formatter.respond_to?(:call)
        formatter.call(self).to_s
      else
        strftime(formatter)
      end
    else
      to_default_s
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

Time使用和也可以完成同样的操作DateTime


Sch*_*ern 5

此功能在 Rails 7 中已被弃用。您可以使用以下命令重新打开它config.active_support.disable_to_s_conversion

不推荐将格式传递给 #to_s,而在数组、范围、日期、日期时间、时间、BigDecimal、Float 和 Integer 中使用 #to_fs。

此弃用是为了允许 Rails 应用程序利用 Ruby 3.1 优化,使某些类型的对象的插值速度更快。

新应用程序不会在这些类上覆盖 #to_s 方法,现有应用程序可以使用 config.active_support.disable_to_s_conversion。

  • 奇怪的是,[Rails 升级指南](https://guides.rubyonrails.org/upgrading_ruby_on_rails.html) 的“从 Rails 6.1 升级到 Rails 7.0”部分中没有提到这一点;我以后还必须记得检查[发行说明](https://edgeguides.rubyonrails.org/7_0_release_notes.html)页面。 (2认同)