Question

Pluralizing a single word is simple:

pluralize(@total_users, "user")

But what if I want to print "There is/are N user/users":

There are 0 users
There is 1 user
There are 2 users

, i.e., how to pluralize a sentence?

Was it helpful?

Solution

You can add a custom inflection for it. By default, Rails will add an inflections.rb to config/initializers. There you can add:

ActiveSupport::Inflector.inflections do |inflect|
  inflect.irregular "is", "are"
end

You will then be able to use pluralize(@total_users, "is") to return is/are using the same rules as user/users.

EDIT: You clarified the question on how to pluralize a sentence. This is much more difficult to do generically, but if you want to do it, you'll have to dive into NLP.

As the comment suggests, you could do something with I18n if you just want to do it with a few sentences, you could build something like this:

  def pluralize_sentence(count, i18n_id, plural_i18n_id = nil)
    if count == 1
      I18n.t(i18n_id, :count => count)
    else
      I18n.t(plural_i18n_id || (i18n_id + "_plural"), :count => count)
    end
  end

  pluralize_sentence(@total_users, "user_count")

And in config/locales/en.yml:

  en:
    user_count: "There is %{count} user."
    user_count_plural: "There are %{count} users."

OTHER TIPS

This is probably best covered by the Rails i18n pluralization features. Adapted from http://guides.rubyonrails.org/i18n.html#pluralization

I18n.backend.store_translations :en, :user_msg => {
  :one => 'There is 1 user',
  :other => 'There are %{count} users'
}
I18n.translate :user_msg, :count => 2
# => 'There are 2 users'

I think the first part of Martin Gordon's answer is pretty good.

Alternatively, it's kind of messy but you can always just write the logic yourself:

"There #{@users.size == 1 ? 'is' : 'are'} #{@users.size} user#{'s' unless @users.size == 1}."

UPDATE to code: I no longer use the inflections route as stated in @Martin Gordon's answer. For some reason it would cause other non-related functions to error. I did extensive tests to confirm, though could not track down a reason why. So, below is now what I use and it works.

There are many ways to do this. This is how I did it using Rails 6.0.3.4 and Ruby 2.7.1.

I wanted to pluralize this sentence:

  • Singular: There is 1 private group
  • Plural: There are 2 private groups

What I did is I went to application_helper.rb and added this code:

def pluralize_private_statement(list, word)
  num_in_list = list.count
  is_or_are = num_in_list == 1 ? 'is' : 'are'
  return "There " + is_or_are + " " + num_in_list.to_s + " private " + word.pluralize(num_in_list)
end

Now, all I have to use in my view is:

<%= pluralize_private_statement(private_groups, "group") %>
# private_groups = 2
# -> There are 2 private groups

What the code in application_helper.rb does is first create a variable for the number of items in the list passed and store it in num_in_list. Then it creates a second varible checking if the num_in_list is equal to 1 and if so returns 'is' otherwise it returns 'are'. Then, it returns the sentence that is constructed with the information obtained.

The first part of the sentence is a simple string, then the is_or_are variable which holds either 'is' or 'are' as explained above. Then it adds a space with the number of list items, converted from an integer to a string, followed by the 'private' word. Then it adds the pluralization of the word passed to the initial function; but, only returns the singular/plural word without a number attached as pluralize(@total_users, "is") would do.

Here is how you could use it for your specific question.

First, add this to your application_helper.rb file:

def pluralize_sentence(list, word)
  num_in_list = list.count
  is_or_are = num_in_list == 1 ? 'is' : 'are'
  return "There " + is_or_are + " " + num_in_list.to_s + " " + word.pluralize(num_in_list)
end

Lastly, you can use this code wherever you wish to have the pluralized sentence:

<%= pluralize_sentence(@total_users, "user") %>

Happy Coding!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top