kopongo.com

home

Rails Inflector problems

04 Nov 2007

I knew that the rails pluralization did some cool fancy stuff, but never really had to mess with it until today. I was trying to duplicate some bug I ran into, so I created a brand new rails app to recreate the bug in there. I had to create some model, so created "Dive", and did the whole scaffold thing that goes along with it.

I ran the tests, and they then started to complain about "Dife" not being found.

Curious, I went to the console:

    % "dives".singularize   # => dife

Huh? What's a 'dife'? Even dictionary.com does not even know what a 'dife' is! No matter, I knew that you could fix this up in the environment.rb file. I went in there and uncommented that default block in there, and added my little contribution to rails' knowledge of the english language.

     Inflector.inflections do |inflect|
        inflect.singular /dives/i, 'dive'
     end

I then ran the console again, just to make sure. First thing I see are all these errors on the command line:

    ./script/../config/../config/environment.rb:55:NameError: uninitialized constant Inflector
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/assertions/selector_assertions.rb:525:NoMethodError:      undefined method `camelize' for "top":String
    ..../app/controllers/application.rb:4:NameError: uninitialized constant ActionController::Base

On the prompt, I try the 'dives'.singularize again, but only get an error.

    >> "dives".singularize
    NoMethod Error: undefined method `singularize' for "dives":String
      from (irb):2

I look in the awdwr book and some other places, and find that what I added really does seem to be correct. A little googling on the error finally takes me to someone else that ran into the same problem.

It's really simple. The Inflector block needs to be outside the whole 'Rails::Initializer.run' block, not inside. Once you move it to the right place, you get what you expect:

    >> "dive".pluralize
    => "dives"
    >> "dives".singularize
    => "dive"