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

如何在Rails i18n YML文件中嵌入Ruby代码实现复数化?

Ah, I see the issue here—you're trying to embed ERB-style Ruby code directly in your YAML locale file, which won't work out of the box because Rails doesn't parse ERB in .yml files by default. Plus, you don't need to do that anyway—Rails I18n has built-in pluralization handling designed exactly for this scenario!

Solution: Use Rails I18n's Native Pluralization

Let's fix this properly by leveraging the framework's built-in tools instead of hacking in Ruby code. Here's how to set it up:

1. Configure Your Locale File (config/locales/en.yml)

Define your pluralized message using the standard one and other keys (Rails uses these for English pluralization by default). You can either hardcode the post labels or tie them to your model's human-readable name:

Option A: Simplified (no model dependency)

en:
  profile:
    remaining_posts:
      one: "This profile still contains %{count} post"
      other: "This profile still contains %{count} posts"

Option B: Tied to your model's human name

If you want to reuse the model's human-readable label (from Post.model_name.human), first define it in your locales, then reference it in the message:

en:
  # Define your model's human-readable pluralized names
  activerecord:
    models:
      post:
        one: "post"
        other: "posts"

  # Your pluralized message
  profile:
    remaining_posts:
      one: "This profile still contains %{count} %{post}"
      other: "This profile still contains %{count} %{posts}"

2. Call the Translation in Your Code

Render the correct pluralized message by passing the count parameter to Rails' t (translate) helper:

For the simplified option:

# In a view
<%= t('profile.remaining_posts', count: @post_count) %>

# Or in a controller
flash[:info] = t('profile.remaining_posts', count: @post_count)

For the model-tied option:

# In a view
<%= t('profile.remaining_posts', count: @post_count,
     post: Post.model_name.human(count: 1).downcase,
     posts: Post.model_name.human(count: @post_count).downcase) %>

Why Your Original Approach Didn't Work

Your initial attempt had two key issues:

  • Rails doesn't process ERB code in .yml files by default (renaming to en.yml.erb is possible but not recommended for locale files, as it breaks standard I18n patterns).
  • It bypassed Rails' purpose-built pluralization system, which handles edge cases and works seamlessly across multiple languages if you ever need to localize your app.

Bonus: Even Cleaner Reusable Setup

If you want to avoid repeating model name parameters, define a standalone pluralized label key and reference it:

en:
  post_label:
    one: "post"
    other: "posts"

  profile:
    remaining_posts: "This profile still contains %{count} %{post_label}"

Then call it like this:

t('profile.remaining_posts', count: @post_count, post_label: t('post_label', count: @post_count))

内容的提问来源于stack exchange,提问作者João Souza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:27:29