Mat*_*age 41 localization ruby-on-rails internationalization ruby-on-rails-3
我正在开发一个Rails 3项目,在该项目中可以在表单中输入日期.带有日期的文本字段使用日期选择器,因此不会担心以错误的格式输入日期,但是日期以:db格式显示(例如2010-01-21).
(注意:这特别是在表单字段中 - 例如<%= f.text_field :publish_date %>
,应该自动使用:默认格式,并且不需要提供值)
我尝试添加具有以下日期配置的自定义区域设置:
date:
formats:
# Use the strftime parameters for formats.
# When no format has been given, it uses default.
# You can provide other formats here if you like!
default: "%d/%m/%Y"
short: "%b %d"
long: "%B %d, %Y"
Run Code Online (Sandbox Code Playgroud)
然后将我的语言环境设置为this(config.i18n.default_locale = "en-AU"
)然而这似乎没有采取,它变得非常令人沮丧.
该应用程序最终将支持许多语言环境,因此在应用程序启动时设置初始化程序以覆盖日期格式并不合适,我知道这应该可行 - 我猜这里错过了一些东西.
语言环境文件是:config/locales/en-AU.yml
并且在我的application.rb中我包括:
config.i18n.load_path += Dir[Rails.root.join("config", "locales", "*.yml").to_s]
config.i18n.default_locale = "en-AU"
Run Code Online (Sandbox Code Playgroud)
在我的application.rb文件中.
Dam*_*IEU 85
显示日期时,您可以使用 I18n.l
所以你会这样做:
I18n.l @entry.created_at
Run Code Online (Sandbox Code Playgroud)
如果你想改变它的格式:
I18n.l @entry.created_at, :format => :short
Run Code Online (Sandbox Code Playgroud)
在国际化的轨道导向是记录这一点.
看看delocalize gem,它可能会帮到你一些.
https://github.com/clemens/delocalize
http://www.railway.at/articles/2009/05/03/new-plugin-delocalize/
@ damien-mathieu有一个可靠的答案显示本地化日期I18n.localize
,他的评论提出了一个重要的警告:这打破了表单文本输入.从那以后,rails给了我们一个很好的解决方案.
从Rails 5开始,您可以使用 Rails属性API来自定义用户输入转换为模型或数据库值的方式.实际上,它在Rails 4.2中可用,但没有完整记录.
通过Sean Griffin的努力,所有模型的类型现在被定义为ActiveRecord::Type
对象.这定义了如何处理属性的单一事实来源.该类型定义了属性的序列化方式(从ruby类型到数据库类型),反序列化(从数据库类型到ruby类型)和强制转换(从用户输入到ruby类型).这是一个大问题,因为搞乱这个曾经是开发人员应该避免的特殊情况的雷区.
首先,浏览attribute
文档以了解如何覆盖属性的类型.您可能需要阅读文档才能理解这个答案.
这是Rails属性API的快速浏览.你可以跳过这一部分,但是你不会知道这些东西是如何工作的.这有什么乐趣?
了解Rails如何处理属性的用户输入将让我们只覆盖一种方法,而不是制作更完整的自定义类型.它还可以帮助您编写更好的代码,因为rails的代码非常好.
既然你没有提到一个模型,我会假设你有Post
一个:publish_date
属性(有些人更喜欢这个名字:published_on
,但我离题了).
找出什么类型:publish_date
.我们不关心它是一个实例Date
,我们需要知道type_for_attribute返回什么:
对于与模型属性类型相关的任何事物,此方法是唯一有效的信息源.
$ rails c
> post = Post.where.not(publish_date: nil).first
> post.publish_date.class
=> Date
> Post.type_for_attribute('publish_date').type
=> :date
Run Code Online (Sandbox Code Playgroud)
现在我们知道:publish_date
属性是一种:date
类型.这是由ActiveRecord :: Type :: Date定义的,它扩展了ActiveModel :: Type :: Date,它扩展了ActiveModel :: Type :: Value.我已经链接到rails 5.1.3,但您需要阅读您的版本的源代码.
因此,当您设置时:publish_date
,该值将传递给cast,后者调用cast_value.由于表单输入是一个String,它将尝试使用Date._parse的fast_string_to_date然后fallback_string_to_date.
如果你迷路了,别担心.您无需了解rails的代码即可自定义属性.
现在我们已经了解了Rails如何使用属性API,我们可以轻松地创建自己的属性.只需创建一个自定义类型来覆盖cast_value
以期望本地化的日期字符串
class LocalizedDate < ActiveRecord::Type::Date
private
# Convert localized date string to Date object. This takes I18n formatted date strings
# from user input and casts them back to Date objects.
def cast_value(value)
if value.is_a?(::String)
return if value.empty?
format = I18n.translate("date.formats.short")
Date.strptime(value, format) rescue nil
elsif value.respond_to?(:to_date)
value.to_date
else
value
end
end
end
Run Code Online (Sandbox Code Playgroud)
看看我是如何复制rails的代码并做了一些小调整.简单.您可能希望通过调用super
并将:short
格式移动到选项或常量来改进此功能.
注册您的类型,以便它可以用符号引用:
# config/initializers/types.rb
ActiveRecord::Type.register(:localized_date, LocalizedDate)
Run Code Online (Sandbox Code Playgroud)
:publish_date
使用您的自定义类型覆盖类型:
class Post < ApplicationRecord
attribute :publish_date, :localized_date
end
Run Code Online (Sandbox Code Playgroud)
现在,您可以在表单输入中使用本地化值:
# app/views/posts/_form.html.erb
<%= form_for(@post) do |f| %>
<%= f.label :publish_date %>
<%= f.text_field :publish_date, value: (I18n.localize(value, format: :short) if value.present?) %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
36183 次 |
最近记录: |