Module: ClassMethods

Defined in:
lib/olson/class_methods.rb

Instance Method Summary collapse

Instance Method Details

#default_humanize(value) ⇒ Object

The default way to humanize a value when not found in I18n.

To configure the default humanization, you can override ‘.default_humanize` in your decorator. For example, to use `String#titleize` instead of `String#humanize`:

# user_decorator.rb
class UserDecorator < ApplicationDecorator
  decorates :user

  def self.default_humanize(value)
    value.to_s.titleize
  end
end


98
99
100
# File 'lib/olson/class_methods.rb', line 98

def default_humanize(value)
  value.to_s.humanize
end

#humanize(attribute, value, default = default_humanize(value)) ⇒ Object

Humanize an attribute using I18n, falling back to the humanized attributes value.

The ‘.default_humanize` method can be overridden to configure how values are humanized when they are not found in I18n.

I tend to store attributes like ‘status` or `role` as underscored strings (a string that would be suitable for a method/variable name) sometimes a simple .humanize will do the trick when it comes to displaying that value in the UI user but other times you need to customize them a bit which is one reason I18n is great. This helps automate the usage of I18n for such a purpose.

Contrived Example:

# user_decorator.rb
class UserDecorator < ApplicationDecorator
  decorates :user

  def activation_status
    humanize :activation_status
  end

  def plan_status
    humanize :plan_status
  end
end

# en.yml
en:
  active: Current
  user:
    activation_status:
      active: 'Activated'

# Examples:
@user.activation_status = 'active';
@user.decorator.activation_status # => 'Activated'

@user.plan_status = 'active'
@user.decorator.plan_status # => 'Current'

@user.activation_status = 'inactive'
@user.decorator.activation_status # => 'Inactive'


80
81
82
# File 'lib/olson/class_methods.rb', line 80

def humanize(attribute, value, default = default_humanize(value))
  i18n_with_scoped_defaults value, [model_name.i18n_key, attribute], default if value.present?
end

#humanizes(*attrs) ⇒ Object

By default, humanize the attributes listed.

Contrived Example:

class UserDecorator < ApplicationDecorator
  decorates :user

  humanizes :activation_status, :plan_status

  # Is a shortcut for:

  def activation_status
    humanize :activation_status
  end

  def plan_status
    humanize :plan_status
  end
end

See ApplicationDecorator.humanize for a more detailed example.



24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/olson/class_methods.rb', line 24

def humanizes(*attrs)
  attrs.each do |attr|
    define_method attr do         # def status
      humanize attr               #   humanize :status
    end                           # end

    attr_options = :"#{ attr }_options"
    define_singleton_method attr_options do   # def status_options
      options_for_select_with_i18n attr,      #   options_for_select_with_i18n 'status',
        source_class.send(attr_options)       #     User.status_options
    end                                       # end
  end
end

#i18n_with_scoped_defaults(key, scope = [], default = key.to_s.humanize) ⇒ Object

Try to translate a key with I18n and a scope but fallback to less-and-less scope. An example will explain more clearly:

i18n_with_scoped_defaults(:some_key, [:foo, :bar, :baz])

Will try the following I18n translations in order:

  • foo.bar.baz.some_key

  • foo.bar.some_key

  • foo.some_key

  • some_key

And if none of the I18n keys translate, it will use the default param (which defaults to humanizing the provided key).

The final call to I18n will be:

I18n.t :'foo.bar.baz.some_key', defaults: [
  :'foo.bar.some_key', :'foo.some_key', :some_key, 'Some key'
]

REVIEW: Should the root :some_key be used? or should i18n_with_scoped_defaults skip it?



124
125
126
127
128
129
130
131
132
133
# File 'lib/olson/class_methods.rb', line 124

def i18n_with_scoped_defaults(key, scope = [], default = key.to_s.humanize)
  scope << key
  key = scope.join('.').to_sym

  defaults = []
  defaults << scope.join('.').to_sym while scope.delete_at(-2)
  defaults << default

  I18n.t key, default: defaults
end

#options_for_select_with_i18n(attribute, options) ⇒ Object

Use humanize to generate select options for an attribute and given options.

Example usage:

# user.rb
class User < AR::Base
  ROLE_OPTIONS = %w(admin user)
  ...
end

# user_decorator.rb
class UserDecorator < ApplicationDecorator
  humanizes :role

  def self.role_options
    options_for_select_with_i18n :role, User::ROLE_OPTIONS
  end
end

# admin/users/edit.html.erb
<%= simple_form_for @user do |f| %>
  <%= f.input :role, collection: UserDecorator.role_options %>
...


159
160
161
162
163
# File 'lib/olson/class_methods.rb', line 159

def options_for_select_with_i18n(attribute, options)
  options.map do |option|
    [ humanize(attribute, option), option ]
  end
end