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

带命名空间的Rails模型嵌套属性错误提示翻译方法咨询

如何翻译嵌套模型Professional::Service的错误提示

要让嵌套的Professional::Service属性错误用上你的葡萄牙语翻译,只需要搞定这几个关键点:

1. 让父模型验证关联的子模型

首先得确保Professional::Company会触发子模型的验证,这样子模型的错误才会被关联到父模型的错误集合里,方便统一处理。在你的公司模型里添加validates_associated:

class Professional::Company < ApplicationRecord
  has_many :professional_services, class_name: 'Professional::Service', dependent: :destroy, foreign_key: 'professional_company_id', inverse_of: :professional_company
  accepts_nested_attributes_for :professional_services
  validates_associated :professional_services # 新增这行,启用关联验证
end

2. 完善pt-BR.yml的翻译配置

你现有的属性翻译已经到位,但补充模型名称和错误消息格式会让提示更符合葡萄牙语习惯:

pt-BR:
  activerecord:
    # 配置模型的显示名称(错误提示里会用到)
    models:
      professional/company: 'Empresa'
      professional/service: 'Serviço'
    # 你的属性翻译保留,这里优化表述更自然
    attributes:
      professional/company:
        name: 'Nome'
        description: 'Descrição'
      professional/service:
        description: 'Descrição do serviço'
        name: 'Título do serviço'
    # 配置错误消息的格式和通用提示
    errors:
      format: "%{attribute} %{message}" # 控制错误消息结构,比如"属性名 错误内容"
      messages:
        blank: 'não pode ficar em branco'
        # 可根据需求添加其他常用错误,比如taken: 'já está em uso'

3. 在视图中正确渲染所有错误

Rails的full_messages方法会自动帮你把翻译后的属性名和错误消息组合起来。在表单里遍历父模型的所有错误即可:

<% if @professional_company.errors.any? %>
  <div class="error-explanation">
    <h2><%= pluralize(@professional_company.errors.count, "erro") %> impediu que essa empresa fosse salva:</h2>
    <ul>
      <% @professional_company.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>

如果需要给每个嵌套服务字段单独显示错误,直接遍历service.errors.full_messages也会自动用上翻译后的文本。

原理很简单:启用关联验证后,父模型保存时会触发子模型的校验,子模型的错误会被Rails整合到父模型的错误集合中;而你配置的yml会告诉Rails用葡萄牙语的属性名和错误文本替换默认提示。

内容的提问来源于stack exchange,提问作者Léo Rocha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:10:53