《基础 Ruby on Rails》的示例程序asagao与Rails2.2相适应
错误信息的国际化(3)
接着上一章继续进行示例应用程序asagao的错误信息的国际化。
member.rb 中有如下描述。
# 值的验证
def validate
if member_number and !Member.positive_integer?(member_number)
errors.add(:member_number, '以1以上的整数输入。')
end
if !email.blank? and !email.well_formed_as_email_address?
errors.add(:email, '格式错误。')
end
if birthday and !birthday.is_valid?
errors.add(:birthday, '日期不存在。')
end
if member_image and member_image.data.size > 65535
errors.add(:uploaded_image,
'尺寸过大(最大64KB)。')
end
end
使用 Errors#add 进行错误注册时,怎样指定错误信息更为便捷呢?
这也是这次的主题。
Errors#add 的 API 在 Rails2.2 中有少许变化。
这是Rails2.1.2的源代码。
def add(attribute, msg = @@default_error_messages[:invalid])
@errors[attribute.to_s] = [] if @errors[attribute.to_s].nil?
@errors[attribute.to_s] << msg
end
第二参数中用字符串指定了错误信息,但是省略的话便成了@@default_error_messages[:invalid] 的値(没有被覆盖的话 'is invalid')。
Rails 2.2.2 中变成这样。
def add(attribute, message = nil, options = {})
message ||= :invalid
message = generate_message(attribute, message, options) if message.is_a?(Symbol)
@errors[attribute.to_s] ||= []
@errors[attribute.to_s] << message
end
第 2 参数中指定了符号的话,根据翻译文件转换。
首先,将刚才的 member.rb 修改如下。
# 值的验证
def validate
if member_number and !Member.positive_integer?(member_number)
errors.add(:member_number, :positive_integer)
end
if !email.blank? and !email.well_formed_as_email_address?
errors.add(:email, :invalid_format)
end
if birthday and !birthday.is_valid?
errors.add(:birthday, :invalid_date)
end
if member_image and member_image.data.size > 65535
errors.add(:uploaded_image, :too_large)
end
end
接下来,将 config/locales/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: Password
administrator: Administrator
uploaded_image: Uploaded Image
blog_entry:
heading: Heading
body1: Body 1
body2: Body 2
note: Note
blog_date: Date
group:
name: Name
remarks: Remarks
article:
place: Place
heading: Heading
body: Body
note: Note
released_at: Released at
expired_at: Expired at
errors:
messages:
positive_integer: "must be a positive integer"
invalid_format: "has an invalid format"
invalid_date: "is an invalid date"
models:
member:
attributes:
uploaded_image:
too_large: "is too large (maximum is 64KB)"
之后,对 config/locales/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: 图像'
blog_entry:
heading: 标题
body1: 正文
body2: 续
note: 注
blog_date: 日期
group:
name: 名称
remarks: 备注
article:
place: 发表地
heading: 标题
body: 正文
note: 注
released_at: 发表开始时间
expired_at: 发表结束时间
errors:
messages:
inclusion: "列表中没有。"
exclusion: "预约中。"
invalid: "错误值。"
confirmation: "不一致。"
accepted: "接受。"
empty: "为空。"
blank: "为空。"
too_long: "{{count}}字内输入。"
too_short: "{{count}}字以上输入。"
wrong_length: "以{{count}}文字输入。"
taken: "已被使用。"
not_a_number: "以数字形式输入。"
greater_than: "指定大于{{count}}的值。"
greater_than_or_equal_to: "指定{{count}}以上的値。"
equal_to: "指定{{count}}。"
less_than: "指定小于{{count}}的値。"
less_than_or_equal_to: "指定{{count}}以下的値。"
odd: "指定奇数。"
even: "指定偶数。"
positive_integer: "以1以上的整数输入。"
invalid_format: "格式错误。"
invalid_date: "不存在的日期。"
models:
member:
taken: 与其它重复。
attributes:
password:
confirmation: 密码错误。
uploaded_image:
too_large: "尺寸过大(最大64KB)。"
不仅 Errors#add ,validates_format_of 等的方法也可以在 :message 选项中指定符号。
member.rb 中有如下记述。
validates_format_of :phone,
:with => /^\d+(-\d+)*$/,
:message => '格式错误。',
:if => Proc.new {|member| !member.phone.blank? }
Rails 2.2 中是这样写的。
validates_format_of :phone,
:with => /^\d+(-\d+)*$/,
:message => :invalid_format,
:if => Proc.new {|member| !member.phone.blank? }
通过rake test 确认测试通过,浏览器中进行测试。
于是,发现了错误。
登录中的用户尝试将自己的帐户信息改成不正确的值,于是 NoMethodError 变发生了。
功能测试未覆盖部分的存在,导致错误在根据脚本进行的测试中没有被发现。
在这种情况下,通常并不马上改正,而是为了再现错误而修改功能测试以后,再修改应用程序本身。
打开test/functional/accounts_controller_test.rb 。
留意一下测试 update 动作的代码,发现存在两个 test_update2 。
总之,第一个的 test_update2 被覆盖,尚未运行。
我确实感到丢人。
将第二个 test_update2 改成 test_update3 后执行功能测试,测试失败。
接着,将 app/views/accounts/_errors.rhtml 的第13行做如下修改。
<span class="attributeWithErrors"><%= h(Member.human_attribute_name(attrib.to_s)) %></span> <%= h(msg) %>
将attrib 变成 attrib.to_s 。
这次的教训应该是“写测试的时候不要过分自信”吧。
(2009/01/17)
- 前言
- 功能测试开头部分的修改等 (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)

