在Mobility gem中,能否使用区域设置以外的其他上下文参数?
扩展Mobility Gem实现多上下文文本展示
核心思路
Mobility本身聚焦多语言翻译,要实现「语言+行业/地区」这类多上下文匹配,核心是给翻译记录增加上下文维度字段,并修改查询逻辑,让字段读取时同时匹配语言和指定上下文。
具体实现步骤
1. 扩展翻译表结构
首先需要给Mobility生成的翻译表(比如post_translations)添加一个context字段,用来存储行业/地区这类标识(字符串类型即可)。
执行迁移:
class AddContextToMobilityTranslations < ActiveRecord::Migration[7.0] def change add_column :post_translations, :context, :string # 可选:添加联合索引提升查询效率,避免重复记录 add_index :post_translations, [:translatable_id, :translatable_type, :key, :locale, :context], unique: true, name: 'idx_mobility_translations_full' end end
2. 自定义Mobility Backend
扩展Mobility的ActiveRecord Backend,让它支持接收context参数,并在查询翻译时带上该条件。
创建app/models/concerns/mobility_context_backend.rb:
module MobilityContextBackend extend ActiveSupport::Concern included do # 重写翻译查询方法,加入context条件 def find_translations super.where(context: context_value) end # 重写翻译创建方法,自动设置context def build_translation(locale, value) super.tap do |translation| translation.context = context_value if translation.respond_to?(:context=) end end private def context_value # 这里示例从模型的industry属性取上下文,可根据需求修改来源 # 比如从请求上下文(当前用户的行业)获取 translatable.industry || 'default' end end end # 注入到Mobility的ActiveRecord表存储Backend Mobility::Backends::ActiveRecord::Table.include(MobilityContextBackend)
3. 模型配置调整
在需要多上下文翻译的模型中,配置Mobility字段,并确保模型有上下文标识字段(比如industry):
class Post < ApplicationRecord # 存储行业标识,比如'automotive',默认值设为'default' attribute :industry, :string, default: 'default' # 配置需要翻译的字段,使用表存储backend translates :title, :content, backend: :active_record_table end
4. 使用方式
写入多上下文翻译
# 创建西班牙语+汽车行业的专属标题 post = Post.new(industry: 'automotive') post.title_es = 'Título Específico de la Industria Automotriz' post.save # 创建西班牙语+通用场景的标题 post2 = Post.new(industry: 'default') post2.title_es = 'Título General en Español' post2.save
读取对应上下文的文本
# 设置当前语言为西班牙语 I18n.locale = :es # 读取汽车行业的西班牙语标题 post = Post.find_by(industry: 'automotive') puts post.title # 输出 "Título Específico de la Industria Automotriz" # 读取通用场景的西班牙语标题 post2 = Post.find_by(industry: 'default') puts post2.title # 输出 "Título General en Español"
5. 灵活扩展上下文来源
如果上下文是请求级别的(比如当前用户的行业),可以借助request_store gem实现全局上下文传递:
# 先添加依赖到Gemfile:gem 'request_store' # 修改context_value方法 def context_value RequestStore.store[:mobility_context] || 'default' end # 在控制器中设置上下文 class ApplicationController < ActionController::Base before_action :set_mobility_context private def set_mobility_context RequestStore.store[:mobility_context] = current_user&.industry || 'default' end end
注意事项
- 建议给
context字段设置默认值'default',避免查询不到翻译记录 - 联合索引要覆盖所有查询维度,保证数据唯一性和查询效率
- 如果需要多个上下文维度(比如地区+行业),可以把
context改成JSON字段,存储哈希格式(如{region: 'eu', industry: 'automotive'}),再调整查询条件
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

