Search code examples
ruby-on-railsrubyruby-on-rails-5scaffolding

Rails changes slave to slafe when scaffolding


I'm trying to generate a scaffold named "slave". When I run the command rails generate scaffold slave rails changes some parts of the scaffold from slave to slafe. Affected, for instance, are the resource routes.

Why does this happen and how can I fix this problem?

I am using Rails 5.0.2 with JRuby on RubyMine.


Solution

  • This is happening because of an incorrect inflection. Rails inflections take a one-size-fits-all approach that works in most cases but can often catch you out because of how weird English pluralization is. In your case, the plural 'slaves' is being correctly generated from your input 'slave', but during the route helper generation rails evidently needs a singular version of 'slaves' and settles on 'slafe' because of this inflection rule:

    inflect.singular(/([^f])ves$/i, '\1fe')
    

    To fix this simply add a rule of your own:

    # config/initializers/inflections.rb
    ActiveSupport::Inflector.inflections do |inflect|
      inflect.singular('slaves', 'slave')
    end
    

    ...run the generator again and it works:

    $ rake routes | grep slave
                           slaves GET      /slaves(.:format)                                                   slaves#index
                                  POST     /slaves(.:format)                                                   slaves#create
                        new_slave GET      /slaves/new(.:format)                                               slaves#new
                       edit_slave GET      /slaves/:id/edit(.:format)                                          slaves#edit
                            slave GET      /slaves/:id(.:format)                                               slaves#show
                                  PATCH    /slaves/:id(.:format)                                               slaves#update
                                  PUT      /slaves/:id(.:format)                                               slaves#update
                                  DELETE   /slaves/:id(.:format)                                               slaves#destroy
    

    Incidentally, the exact opposite problem can be caused by this rule:

    inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
    

    ...which causes problems with e.g rails generate scaffold cafe - everything that should be 'cafes' becomes 'caves'. Argh!