You need to enable JavaScript to run this app. Mobility gem v1.0.5如何通过locale/fallthrough访问器验证模型翻译
优惠活动
大模型
产品
解决方案
定价
更多

Mobility gem v1.0.5如何通过locale/fallthrough访问器验证模型翻译

Mobility v1.0.5 版本分Locale字段校验实现

核心逻辑

Mobility 默认会把翻译字段的校验错误挂载在虚拟属性(比如通用的:name属性)上,不会自动拆分映射到独立的locale访问器(比如:name_en、:name_de)。要实现错误精准对应到每个独立locale字段,只需要结合locale_accessors、fallthrough_accessors的插件特性,直接把校验规则绑定到分语言的独立访问器上——这样校验触发时,错误会天然存入对应属性的错误列表,完全匹配要求的ActiveModel::Errors结构。

配置步骤

1. 初始化Mobility核心插件

在初始化文件中明确启用所需插件,避免默认行为的干扰:

# config/initializers/mobility.rb
Mobility.configure do |config|
  # 生成分语言独立访问器 name_en/name_de 等
  config.plugins[:locale_accessors].enable
  # 启用空值跨语言兜底的fallthrough访问能力
  config.plugins[:fallthrough_accessors].enable
  # 启用AR集成能力
  config.plugins[:active_record].enable
  # 选用键值对存储作为默认翻译后端
  config.default_backend = :key_value
end

2. 模型中分Locale绑定校验规则

在模型中定义翻译字段后,遍历所有应用启用的可用locale,为每个locale对应的独立访问器编写校验规则,不要将校验直接绑定在虚拟的通用翻译属性上:

class Category < ApplicationRecord
  translates :name, type: :string

  # 遍历启用的locale逐一生成独立校验
  I18n.available_locales.each do |locale|
    attr_name = "name_#{locale}".to_sym
    # 直接在分语言访问器上定义校验,错误会自动关联到对应属性
    validates attr_name,
              uniqueness: { case_sensitive: false },
              length: { maximum: 255 }
  end
end

效果验证

对应测试场景,提前在数据库中存在一条name_en = 'Cat. 1'的已有记录时:

c = Category.new(name_en: 'Cat. 1', name_de: 'Kat. 1')
c.valid?
# => false
# 输出错误结构完全匹配预期
c.errors.messages
# => {:name_en=>["has already been taken"]}
c.errors.details
# => {:name_en=>[{:error=>:taken, :value=>"Cat. 1"}]}

在视图层直接读取错误列表即可生成要求的展示效果:

  • Name (en): 已被占用
  • Name (de): 校验通过

v1.0.5版本专属注意事项

  • 该版本中locale_accessors插件不会自动拆分虚拟翻译属性上的校验规则,直接在通用:name属性上编写的校验错误,始终会挂载在:name键下,无法生成按locale拆分的错误结构,必须逐locale在独立访问器上定义校验。
  • 启用fallthrough访问器时,注意区分「当前locale的原始输入值」和「fallthrough获取的其他locale兜底值」,编写校验时优先判断原始输入是否为空,避免fallthrough的值被误判为当前locale的输入触发错误校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 16:45:07