Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a rails inflection for possessive strings?

I would like to create a method in additional to the default 'foo'.titlecase that will correctly add "possessiveness" to it.

The string is a user's name (<- just did one right there! )

For example: "sam" is the user <%= user.titlecase.possessive + ' Profile' %> => #Sam's Profile

It just needs to handle edge cases like:

Steelers's Profile ( should be Steelers' Profile) Ross's Profile ( should be Ross' Profile )

like image 595
chovy Avatar asked Jul 12 '09 04:07

chovy


3 Answers

I needed this too and so I made the implementation available on github and as a gem on rubygems so you can include it in your project pretty easy.

In rails 3 all you do is

gem "possessive" 

and you will have it.

like image 50
Coderdad Avatar answered Oct 14 '22 00:10

Coderdad


A minor rewrite of BaroqueBobcat's code, for Shoulda lovers (and lovers of the ternary operator):

Initializer:

module StringExtensions
  def possessive
    self + ('s' == self[-1,1] ? "'" : "'s")
  end
end

class String
  include StringExtensions
end

Shoulda spec:

require File.expand_path(File.dirname(__FILE__) + "/../test_helper")

class StringExtensionsTest < ActiveSupport::TestCase
  context 'String' do
    context '#possessive' do
      should "turn sam into sam's" do
        assert_equal "sam's", "sam".possessive
      end
      should "turn Steelers into Steelers'" do
        assert_equal "Steelers'", "Steelers".possessive
      end
    end
  end
end

Edit: see Rimian's answer to this question, which properly handles "who" and "it".

like image 24
Jamie Flournoy Avatar answered Oct 14 '22 00:10

Jamie Flournoy


What you want is pretty trivial to do, given ruby's open classes.

class String
  def possessive
    self + case self[-1,1]#1.8.7 style
    when 's' then "'"
    else "'s"
    end
  end
end


#rspec examples
describe "String#possessive" do
  it "should turn Steelers into Steelers'" do
    "Steelers".possessive.should == "Steelers'"
  end
  it "should turn sam into sam's" do
    "sam".possessive.should == "sam's"
  end
end

You would probably want to put this in a plugin, to keep it separate from your business logic code.

$ script/generate plugin Possessiveate

Then just drop the code to the generated init.rb in the plugin's directory. Pretty much all the other generated files aren't needed, but you might be interested in looking at the default file structure.

like image 15
BaroqueBobcat Avatar answered Oct 14 '22 00:10

BaroqueBobcat