《基础 Ruby on Rails》的示例程序asagao与Rails2.2相适应
ActiveRecord 模型的字段名的国际化
上一章中,在示例应用程序 asagao 中添加了区域切换的功能。
这一章,将着手进行 ActiveRecord 相关的国际化。
使表示某个对象的内容和编辑表单时的字段名能够根据不同的区域进行转换。
在《基础 Ruby on Rails》中,已将常量 REAL_ATTRIBUTE_NAMES 和类方法 real_attribute_name 在每一个模型定义。
例如,在 member.rb 中有如下描述。
# 属性对应的汉字名
REAL_ATTRIBUTE_NAMES = {
:member_number => '球衣号码',
:player => '选手注册',
:family_name => '姓',
:given_name => '名',
:furigana => '注音假名',
:email => 'email',
:phone => '电话号码',
:birthday => '出生年月',
:sex => '性別',
:remarks => '备注',
:login_name => '用户名',
:password => '密码修改',
:administrator => '网站管理者',
:uploaded_image => '图像'
}
def self.real_attribute_name(key)
REAL_ATTRIBUTE_NAMES[key.to_sym]
end
而且,在模板中有如下语句。
<%= Member.real_attribute_name(:phone) %>
从Rails2.2开始,ActiveRecord::Base的类方法 human_attribute_name 可以内部利用 I18n 模块。
决定用新方法进行改写。
那么,开始吧。
首先,为了确定影响范围,将上述代码从 member.rb 删除,执行测试。
单元测试中没有发生错误。这也未必是好事。这意味着 real_attribute_name 方法的测试没被写入。需要检查。
功能测试中,9个测试失败了。
> rake test:functionals (省略) 95 tests, 320 assertions, 9 failures, 0 errors
在 accounts 和 members 和 admin/members 控制台中失败了。和预料一样。
如果用 human_attribute_name 全部置换 real_attribute_name 方法的话,测试应该通过的吧。
用喜欢的编辑器的“统一置换”功能,将 app/views/accounts 、 app/views/members 和 app/views/admin/members 目录下的全部文件中的 real_attribute_name 换成human_attribute_name 。
再次执行功能测试。
> rake test:functionals (省略) 95 tests, 320 assertions, 9 failures, 0 errors
啊!不行。出现了这样的错误。
undefined method `humanize' for :member_number:Symbol
虽然 real_attribute_name 方法获取了符号,但是在 human_attribute_name 方法的情况下有必要使用字符串指定字段名。
这表示有必要将 human_attribute_name(:foo) 置换为 human_attribute_name('foo') 。
虽然也有做如此复杂的置换的编辑器,但是还是让我们来创建一个任何人都能用的小的 Ruby 脚本。
创建一个下面这样的脚本,命名为 humanize.rb 并存在 scrpts 目录下。
dir = ARGV[0]
Dir.glob("app/views/#{dir}/**/*.rhtml").each do |file|
code = File.open(file).read
code.gsub!(/real_attribute_name/, 'human_attribute_name')
code.gsub!(/human_attribute_name\(:(\w+)\)/, 'human_attribute_name("\1")')
File.open(file, 'w').write(code)
end
执行置换。
> ruby script/humanize.rb accounts > ruby script/humanize.rb members > ruby script/humanize.rb admin/members
再次执行功能测试。
> rake test:functionals (省略) 95 tests, 338 assertions, 3 failures, 0 errors
又出现错误了。
原因是app/views/admin/members/_errors.rhtml 。
<strong><%= h(Member.human_attribute_name(attr.to_sym)) %></strong> <%= h(msg) %>
将此做如下修改(去掉.to_sym )。
<strong><%= h(Member.human_attribute_name(attr)) %></strong> <%= h(msg) %>
再次执行功能测试。
> rake test:functionals (省略) 95 tests, 341 assertions, 0 failures, 0 errors
OK 了。
> rake test:integration (省略) 2 tests, 67 assertions, 0 failures, 0 errors
综合测试也通过了。
接下来,生成翻译文件。
在 config/locales 目录下生成 activerecord_en.yml 与 activerecord_ja.yml 。
activerecord_en.yml
en:
activerecord:
attributes:
member:
member_number: Member Number
player: Player
family_name: Family Name
given_name: Given Name
furigana: Furigana
email: E-mail address
phone: Phone Number
birthday: Birthday
sex: Sex
remarks: Remarks
login_name: Login Name
password: Change Password
administrator: Administrator
uploaded_image: Uploaded Image
activerecord_ja.yml
ja:
activerecord:
attributes:
member:
member_number: 球衣号码
player: 选手注册
family_name: 姓
given_name: 名
furigana: 注音假名
email: email
phone: 电话号码
birthday: 出生年月
sex: 性別
remarks: 备注
login_name: 用户名
password: 密码
administrator: 网站管理者
uploaded_image: 图像'
运行服务器,以会员身份登陆。
试着更改自己的帐户,使用会员名册和管理页面的会员管理功能。
然后,切换语言,确认字段名表示正确。
追加新的翻译文件时,因为即使在 develope 环境中也有必要重新启动服务器,所以注意一下。
如果仅是修改翻译文件,则不用重启。


和前面叙述的一样,Rails 2.2 的 human_attribute_name 内部利用了 I18n 模型。
如果写成 Member.human_attribute_name('phone') 的话,便和写成 t('activecord.attributes.member.phone') 一样了。
今天就到这儿吧。
(2009/01/08)
- 前言
- 功能测试开头部分的修改等 (2008/12/01)
- rake rails:update (2008/12/15)
- Cookie Store (2008/12/16)
- 分页 (2008/12/17)
- blog_entries 控制台的修改 (2008/12/20)
- 单例资源 (2008/12/21)
- 一口气通过所有功能测试 (2008/12/21)
- 综合测试和rak (2008/12/22)
- 国际化(i18n)的第一步 (2008/12/26)
- 基于Cookie的区域的切换 (2009/01/04)
- ActiveRecord 模型的字段名的国际化 (2009/01/08)
- 错误信息的国际化(1) (2009/01/09)
- 错误信息的国际化(2) (2009/01/10)
- 错误信息的国际化(3) (2009/01/17)
- 错误信息的国际化(4) (2009/01/24)

