Skip to content
Helps you stop using chains of humanize/downcase/underscore/pluralize/to_sym/etc everywhere in your models, your views, your controllers, etc.
Ruby
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
lib
test
.document
.gitignore
Gemfile
LICENSE
README.rdoc
Rakefile
common_name.gemspec

README.rdoc

common_name

Stop needing to use humanize/downcase/underscore/pluralize/to_sym/etc to derive a common name.

Why this is useful

In our app, we have lots of classes that share something (a name) in common:

  • class Automobile < Emitter

  • class AutomobilesController < EmittersController

  • class AutomobilesComponent < Component

  • class AutomobileVersion < EmitterVersion

  • Boat et al., Flight et al., etc.

Of course, there are a million ways to derive the word “automobile” from any of these class names. We could fill up our app with humanize/downcase/underscore/pluralize, but we think that's sloppy.

So we use common_name:

>> Automobile.common_name
=> "automobile"
>> Automobile.new.common_name
=> "automobile"
>> AutomobilesController.common_name
=> "automobile"
>> AutomobilesController.new.common_name
=> "automobile"
>> AutomobilesComponent.common_name
=> "automobile"
>> AutomobilesComponent.new.common_name
=> "automobile"
>> AutomobileVersion.common_name
=> "automobile"
>> AutomobileVersion.new.common_name
=> "automobile"

And when metaprogramming:

module EmitterVersionExtensions
  def self.included(klass)
    klass.class_eval do
      set_table_name "#{common_name}_versions"        # set_table_name "automobile_versions"
      belongs_to common_symbol                        # belongs_to :automobile
      has_one :profile, :through => common_symbol     # has_one :profile, :through => :automobile
    end
  end
end

We also end up using this constantly in views.

Quick reference

Here are all the methods it gives you:

common_name             => "bus_company"
common_symbol           => :bus_company
common_instance         => "@bus_company"
common_title            => "Bus company"
common_human            => "bus company"
common_camel            => "BusCompany"

common_plural           => "bus_companies"
common_plural_symbol    => :bus_companies
common_plural_instance  => "@bus_companies"
common_plural_title     => "Bus companies"
common_plural_human     => "bus companies"
common_plural_camel     => "BusCompanies"

common_model            => BusCompany [the class]

Quick start

Put this in config/environment.rb

config.gem 'common_name'

Put this in config/initializers/common_name.rb… (it will let you say BusCompany.common_name and get the string “bus_company”)

ActiveRecord::Base.class_eval do
  class << self; def _common_name; name.underscore; end; end
  include CommonName
end

Put this in app/controllers/application_controller.rb… (in the CareersController, it will let you say common_model and get the class Career)

class ApplicationController < ActionController::Base
  class << self; def _common_name; controller_name.singularize; end; end
  include CommonName
end

Put this in app/helpers/application_helper.rb… (in careers/show, it will let you say <%= common_plural_title %> and see “Careers”)

module ApplicationHelper
  CommonName::METHODS.each do |m|
    eval %{ def common_#{m}; controller.common_#{m}; end }
  end
end

What it's not

It's not a replacement for humanize, pluralize, etc.

>> "bus_company".common_title
NoMethodError: undefined method 'common_title' for "bus company":String

The point is to cover common names of classes and their instances.

Advanced usage

The _common_name method should provide an underscored form that will be used to derive other common forms like common_human and common_plural_symbol.

Note that calling common_X on a class and on its instances will return the same value.

I also use it on non-ActiveRecord classes:

class FooBar
  class << self; def _common_name; name.underscore; end; end
  include CommonName
end

>> FooBar.common_name
=> "foo_bar"
>> f.common_name         # f = FooBar.new
=> "foo_bar"

If you define _common_plural, it will be the basis for the plural forms:

class Government
  class << self
    def _common_name
      'government'
    end
    def _common_plural
      'government'
    end
  end
  include CommonName
end

That way you can enforce uncountability

Government.common_name == Government.common_plural

without setting a general rule in the Inflector that the word “government” is uncountable.

Rationale

I don't like chains of humanize/downcase/underscore/pluralize/to_sym, for example:

>> BusCompany.name.underscore.humanize.downcase.pluralize
=> "bus companies"

So I replaced them with easy-to-remember methods like:

>> BusCompany.common_plural_human
=> "bus companies"

I also didn't like worrying about .name versus .class.name:

>> @bus_company.class.name      # @bus_company = BusCompany.new
=> "BusCompany"
>> @bus_company.name
=> ""

So, the common_name of a class (BusCompany) is always equivalent to the common_name of its instances (@bus_company):

>> BusCompany.common_plural_human == @bus_company.common_plural_human
=> true

Copyright

Copyright © 2009 Seamus Abshere. See LICENSE for details.

Something went wrong with that request. Please try again.