Rails provides a built-in pluralization method for String, e.g., "apple".pluralize returns "apples" and "apple".pluralize(1) does "apple" (see this question). However, it works only for English. Is there any easy way to make it work for another language?
Specifically, I want to make it work in Rails 7 for Japanese (ja), in which there is no distinction between the singular and plural forms. So, basically, I want to make pluralization disabled when the (user's) locale I18n.locale is "ja". However, "林檎".pluralize(locale: :ja) returns "林檎s", which is obviously wrong.
The way that works in conjunction with the standard I18n translation framework of Rails would be the best.
Maybe the easiest, but non-DRY way
In Rails,
String#pluralizeis (I understand) based on ActiveSupport::Inflector.pluralize. Although it only supports English, it does not change the String for the other languages (locales), which is what you want:To specify any language but English, the first argument seems mandatory (which is, IMO, both unintuitive and lengthy).
A confusing thing is that the locale is not the keyword argument for
String#pluralize, unlikeActionController::Base.helpers.pluralize, but the optional main argument! If you specify only the locale with a colon in the form of the keyword argument (as in the last line in the example above), the result will be surprising.For the languages that dintinguish singular and plural forms but in a different rule from English, like "un animal" and "des animaux" in French, you can specify your own inflection rule according to the Rails doc.
This is, however, not ideal in the sense this breaks the DRY principle, in which the locale must be specified twice.
Explicitly specifying the plural form
You can achieve a similar thing by using Rails'
countoption in the I18n framework:This method does follow the DRY principle.
However, there are a couple of major downsides. First, I feel, to be honest, it is daft to define the plural forms for all the (perhaps hundreds of?) English words for which you define translations, considering Rails knows how to pluralize those English words.
Second, once you have specified a set of translations like these, you must always call them with the
countoption.In addition, the point of the
countoption inI18n.tis, arguably, you don't have to write the count number twice by including%{count}in the definition. In the example above, I delibrately exclude%{count}so that you can and do get the result without the count number as the OP asks for. However, this method kind of defeats the purposeI18n.t(I18n.translate) is designed for, as you would still have to explicitly specify where and how the number is placed like,This downside is particularly relevant for some languages, which place the number AFTER the main word in some contexts. For example, the American English expression of a day and month "November 7", as opposed to "7 November" (in British English), is an example. Or, the standard currency expressions vary from language to language, like "£4" (en-gb), 10.50 € (fr), 300円 (ja).
An alternative method
You can use
ActionController::Base.helpers.pluralizelike the following example, in combination with your own translations. Although this is not what the OP asks for (that is, to get a plural form without a count number), I here include this for the sake of completeness.A major difference is that the number is forcibly included in the returned String.
The format is also different and is more lengthy, breaking the DRY principle.