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/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.