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

Sequelize模型定义中调用i18next.t返回翻译键而非对应译文

问题根因
  • 执行时机不匹配:Sequelize 模型定义代码会在应用启动阶段同步执行,你在验证规则的msg字段中直接调用i18next.t(),该调用会在模型加载时立刻运行,此时大概率 i18next 还未完成初始化(未加载翻译资源、未设置生效语言),无法匹配到对应翻译值,只会返回原始翻译键。
  • 不支持动态语言切换:即便 i18next 初始化完成,这个写法也只会保留应用启动时的单次翻译结果,后续不同用户请求携带不同语言偏好时,错误消息无法动态切换,不符合多语言业务的使用要求。
解决方案

方案1:业务层统一捕获翻译(更推荐)

模型定义阶段只存储翻译键,不要直接执行翻译:

// candidate.js 模型定义
validate: {
  isIn: {
    args: [allowedTypes],
    msg: 'candidate-invalid-type'
  }
}

在业务逻辑层捕获 Sequelize 验证错误时,结合当前请求的语言上下文执行翻译:

// 业务代码中调用模型操作的位置
try {
  await Candidate.create(params)
} catch (err) {
  if (err.name === 'SequelizeValidationError') {
    const translatedErrors = err.errors.map(item => {
      return i18next.t(item.message, { allowedTypes, joinArrays: ', ' })
    })
    // 后续返回翻译后的错误信息即可
  }
}

该方案可以完全和当前请求的语言上下文绑定,灵活适配多语言切换场景,也方便统一管理所有验证错误的翻译逻辑。

方案2:模型层使用自定义验证函数

如果希望翻译逻辑放在模型层,可以替换静态的msg配置为自定义验证函数,在验证触发时才执行翻译:

type: {
  type: DataTypes.ENUM,
  values: [types.CANDIDATE, types.EMPLOYEE],
  validate: {
    isInAllowedTypes(value) {
      if (!allowedTypes.includes(value)) {
        throw new Error(i18next.t('candidate-invalid-type', { allowedTypes, joinArrays: ', ' }))
      }
    }
  }
}

注意如果是多请求并发的服务场景,需要确保i18next实例和当前请求的语言上下文绑定,不要直接使用全局i18next实例,避免不同请求的语言设置互相串扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:54:07