56

I am writing some Ruby code, not Rails, and I need to handle something like this:

found 1 match
found 2 matches

I have Rails installed so maybe I might be able to add a require clause at the top of the script, but does anyone know of a RUBY method that pluralizes strings? Is there a class I can require that can deal with this if the script isn't Rails but I have Rails installed?

Edit: All of these answers were close but I checked off the one that got it working for me. Try this method as a helper when writing Ruby, not Rails, code:

def pluralize(number, text)
  return text.pluralize if number != 1
  text
end
the Tin Man
  • 150,910
  • 39
  • 198
  • 279
aarona
  • 32,176
  • 39
  • 119
  • 171
  • The edit is not correct. There is no ruby function String#pluralize, you are missing require 'active_support/inflector' or something else. – gorn Jul 20 '12 at 22:19
  • Well Rails is always changing. Feel free to edit my question so its correct. I'm not currently working with rails so I don't have the time to test this and see what the correct way to do this is now. – aarona Aug 13 '12 at 22:30

7 Answers7

77

Actually all you need to do is

require 'active_support/inflector'

and that will extend the String type.

you can then do

"MyString".pluralize

which will return

"MyStrings"

for 2.3.5 try:

require 'rubygems'
require 'active_support/inflector'

should get it, if not try

sudo gem install activesupport

and then the requires.

NullUserException
  • 77,975
  • 25
  • 199
  • 226
scaney
  • 1,686
  • 13
  • 16
  • for 2.3.5 sudo gem install activesupport require 'rubygems' require 'active_support/inflector' should get it I'm using edge rails (3) there's been a lot of decoupling, and it appears to bundle with it by default – scaney Mar 16 '10 at 10:28
  • This is the core of ActiveView's pluralize, however ActiveView#pluralize also knows when it should use the plural or singular version, based on the first parameter. – the Tin Man Dec 03 '10 at 20:54
57

Inflector is overkill for most situations.

def x(n, singular, plural=nil)
    if n == 1
        "1 #{singular}"
    elsif plural
        "#{n} #{plural}"
    else
        "#{n} #{singular}s"
    end
end

Put this in common.rb, or wherever you like your general utility functions and...

require "common" 

puts x(0, 'result') # 0 results
puts x(1, 'result') # 1 result
puts x(2, 'result') # 2 results

puts x(0, 'match', 'matches') # 0 matches
puts x(1, 'match', 'matches') # 1 match 
puts x(2, 'match', 'matches') # 2 matches 
eukras
  • 799
  • 5
  • 4
13

I personally like the linguistics gem that is definitely not rails related.

# from it's frontpage
require 'linguistics'

Linguistics.use :en

"box".en.plural #=> "boxes"
"mouse".en.plural #=> "mice"
# etc
Tim Peters
  • 3,724
  • 2
  • 20
  • 27
hawx
  • 1,263
  • 12
  • 10
2

This works for me (using ruby 2.1.1 and actionpack 3.2.17):

~$ irb
>> require 'action_view'
=> true
>> include ActionView::Helpers::TextHelper
=> Object
>> pluralize(1, 'cat')
=> "1 cat"
>> pluralize(2, 'cat')
=> "2 cats"
1
require 'active_support'
require 'active_support/inflector'

inf = ActiveSupport::Inflector::Inflections.new

to get the inflector, not sure how you use it

scaney
  • 1,686
  • 13
  • 16
1

my solution:

# Custom pluralize - will return text without the number as the default pluralize.
def cpluralize(number, text)
  return text.pluralize if number != 1 
  return text.singularize if number == 1
end

So you can have 'review' returned if you call cpluralize(1, 'reviews')

Hope that helps.

Giang Nguyen
  • 919
  • 10
  • 19
0

I've defined a helper function for that, I use it for every user editable model's index view :

  def ovyka_counter(array, name=nil, plural=nil)
    name ||= array.first.class.human_name.downcase
    pluralize(array.count, name, plural)
  end

then you can call it from the view :

<% ovyka_counter @posts %>

for internationalization (i18n), you may then add this to your locale YAML files :

  activerecord:
    models:
      post: "Conversation"