You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Minitest测试Mobility Gem翻译存在性验证的问题

问题分析与解决步骤

1. 定位Name can't be blank错误根源

这个错误说明当前测试环境下,Mobility代理的name属性(对应焦点语言的翻译)为空——你在fixture里填了name: MyString,但大概率是以下原因导致验证失败:

  • 测试环境默认Locale不是en,导致name代理的是非en的翻译字段,而该字段未在fixture中填充;
  • Mobility的fixture加载逻辑中,name字段默认映射的Locale与你的预期不符。

2. 快速验证Locale问题

在测试代码中临时添加Locale输出,确认当前环境的Locale:

test "validity of fixtures" do
  puts "Current test locale: #{I18n.locale}" # 查看输出是否为:en
  assert tags(:en_assigned).valid?
end

3. 修复测试与Fixture

方案一:显式指定测试Locale

如果测试环境默认Locale不是en,在测试中用I18n.with_locale强制切换:

test "validity of fixtures" do
  I18n.with_locale(:en) do
    assert tags(:en_assigned).valid?
  end
end

方案二:补全Fixture的所有Locale翻译

因为你循环验证了所有可用Locale的name_#{locale}字段的presence,所以Fixture需要填充所有对应字段。假设I18n.available_locales包含:en和:zh-CN,Fixture应改为:

en_assigned:
  name_en: MyString
  name_zh-CN: 我的标签

4. 优化Mobility验证逻辑(可选)

Mobility本身提供了多Locale验证的快捷方式,不需要手动循环生成name_#{locale}的验证规则,替换成以下代码更简洁可靠:

validates :name, presence: true, mobility: { locale: I18n.available_locales }

这会同时验证焦点语言的name属性,以及所有可用Locale的翻译存在性。

5. 修复自定义验证器的BUG

当前的translation_exists?方法没有排除当前记录本身,当更新已存在的记录时,会误判为重复。修改为:

private

def translation_exists?(record, attribute)
  attribute_name, locale = attribute.to_s.split('_')
  query = record.class.joins(:string_translations).where(
    mobility_string_translations: { locale: locale, key: attribute_name }
  )
  # 排除当前记录,避免更新时误判
  query = query.where.not(id: record.id) if record.persisted?
  query.exists?
end

内容的提问来源于stack exchange,提问作者Jerome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 21:17:35