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

Rails ignores the default date format after upgrading from 6.1 to 7.0

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

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

这在 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" 

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

此功能是 deprecated in Rails 7。您可以使用 config.active_support.disable_to_s_conversion

将其重新打开

Deprecate passing a format to #to_s in favor of #to_fs in Array, Range, Date, DateTime, Time, BigDecimal, Float and, Integer.

This deprecation is to allow Rails application to take advantage of a Ruby 3.1 optimization that makes interpolation of some types of objects faster.

New applications will not have the #to_s method overridden on those classes, existing applications can use config.active_support.disable_to_s_conversion.

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

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

你有两种选择来解决这个问题

  1. 找到您需要以所选格式显示日期的所有位置并添加 .to_fs。这可能是更正确的解决方法。
  2. 或者做我们所做的,违背 rails 开发者的意愿。添加一个重写日期 .to_s 方法的初始化程序,因为要到 9000 多个不同的位置将 .to_fs 添加到代码中的每个日期显示中,您现在无法考虑太多。

/config/intitializers/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