Search code examples
ruby-on-railstwitter-bootstrapgeneratortwitter-bootstrap-rails

Why do twitter-bootstrap-rails generated views use model_class.human_attribute_name(:column) instead of just a string?


With twitter-bootstrap-rails installed, using the generator:

rails g bootstrap:themed Model

creates views that contain lines such as:

  <th><%= model_class.human_attribute_name(:comment_date) %></th>
  <th><%= model_class.human_attribute_name(:comment_time) %></th>

where the default rails generator just inserts the human readable column name directly:

 <th>Comment date</th>
 <th>Comment time</th>

which makes for cleaner views, and seems like it would be more efficient at run-time.

Is there a benefit to the twitter-bootstrap-rails generated views?

Thanks!

(PS, The developers website is offline, and neither github nor google+ allow sending private messages, and neither an "issue" on github nor a public comment on a google+ post seemed appropriate for this question, so hoping someone here might be familiar with the use-case for model_class.human_attribute_name())


Solution

  • Take a look at its source and things will get clear to you:

    # File activemodel/lib/active_model/translation.rb, line 45
    def human_attribute_name(attribute, options = {})
      defaults  = []
      parts     = attribute.to_s.split(".", 2)
      attribute = parts.pop
      namespace = parts.pop
    
      if namespace
        lookup_ancestors.each do |klass|
          defaults << :"#{self.i18n_scope}.attributes.#{klass.model_name.i18n_key}/#{namespace}.#{attribute}"
        end
        defaults << :"#{self.i18n_scope}.attributes.#{namespace}.#{attribute}"
      else
        lookup_ancestors.each do |klass|
          defaults << :"#{self.i18n_scope}.attributes.#{klass.model_name.i18n_key}.#{attribute}"
        end
      end
    
      defaults << :"attributes.#{attribute}"
      defaults << options.delete(:default) if options[:default]
      defaults << attribute.humanize
    
      options.reverse_merge! :count => 1, :default => defaults
      I18n.translate(defaults.shift, options)
    end
    

    human_attribute_name does a great job for localizing your attribute names. Even if you're building app which uses English exclusively -- who knows, maybe your inbox already has an email from your client about his plans on expanding business and this expansion will include countries where people write right-to-left.

    How it works

    Assume you have Product model with title attribute. Calling human_attribute_name this way:

    Product.human_attribute_name 'title'
    

    will call I18n.t (see the last line in the snippet above) with the following parameters:

    I18.t 'activerecord.attributes.product.title', {
      :count=>1, 
      :default=>[:"attributes.title", "Title"] 
    }
    

    So, you can provide translations specific to some model and specific to some attribute's name. Unless you provide any of these translations you'll get English version of your attribute created via humanize method.