module EnumExt::HumanizeHelpers

Public Class Methods

define_superset_humanization_helpers(base_class, superset_name, enum_name) click to toggle source

t_… methods for supersets will just slice original enum t_.. methods output and return only superset related values from it

# File lib/enum_ext/humanize_helpers.rb, line 110
def self.define_superset_humanization_helpers(base_class, superset_name, enum_name)
  enum_plural = enum_name.to_s.pluralize

  base_class.send(enum_plural).define_singleton_method( "t_#{superset_name}_options" ) do
    result = evaluate_localizations(send("t_#{superset_name}"))
    return result unless result.blank?

    [["Enum translations call missed. Did you forget to call translate #{enum_name}"]*2]
  end

  # enums.t_options_i
  base_class.send(enum_plural).define_singleton_method( "t_#{superset_name}_options_i" ) do
    result = evaluate_localizations_to_i( send("t_#{superset_name}") )
    return result unless result.to_h.values.all?(&:blank?)

    [["Enum translations are missing. Did you forget to translate #{enum_name}"]*2]
  end


  # enums.t_superset ( translations or humanizations subset for a given set )
  base_class.send(enum_plural).define_singleton_method( "t_#{superset_name}" ) do
    return [(["Enum translations are missing. Did you forget to translate #{enum_name}"]*2)].to_h if localizations.blank?

    base_class.send(enum_plural).localizations.slice( *base_class.send(enum_plural).send(superset_name) )
  end
end

Public Instance Methods

human_attribute_name( name, options = {} ) click to toggle source

human_attribute_name is redefined for automation like this: p #{object.class.human_attribute_name( attr_name )}: p object.send(attr_name)

Calls superclass method
# File lib/enum_ext/humanize_helpers.rb, line 101
def human_attribute_name( name, options = {} )
  # if name starts from t_ and there is a column with the last part then ...
  name[0..1] == 't_' && column_names.include?(name[2..-1]) ? super( name[2..-1], options ) : super( name, options )
end
humanize_enum( *args, &block ) click to toggle source

if app doesn’t need internationalization, it may use humanize_enum to make enum user friendly

class Request

humanize_enum :status, {
  #locale dependent example with pluralization and lambda:
  payed: -> (t_self) { I18n.t("request.status.payed", count: t_self.sum ) }

  #locale dependent example with pluralization and proc:
  payed: Proc.new{ I18n.t("request.status.payed", count: self.sum ) }

  #locale independent:
  ready_for_shipment: "Ready to go!"
}

end

Could be called multiple times, all humanization definitions will be merged under the hood:

humanize_enum :status, {
   payed: I18n.t("scope.#{status}")

} humanize_enum :status, {

billed: I18n.t("scope.#{status}")

}

Example with block:

humanize_enum :status do

I18n.t("scope.#{status}")

end

in views select:

f.select :status, Request.t_statuses_options

in select in Active Admin filter

collection: Request.statuses.t_options_i

Rem: select options breaks when using lambda() with params

Console:

request.sum = 3
request.payed!
request.status     # >> payed
request.t_status   # >> "Payed 3 dollars"
Request.t_statuses # >> { in_cart: -> { I18n.t("request.status.in_cart") }, ....  }
# File lib/enum_ext/humanize_helpers.rb, line 47
def humanize_enum( *args, &block )
  enum_name = args.shift
  localization_definitions = args.pop
  enum_plural = enum_name.to_s.pluralize

  self.instance_eval do
    # instance.t_enum
    define_method "t_#{enum_name}" do
      t = block || self.class.send(enum_plural).localizations[send(enum_name)]
      if t.try(:lambda?)
        t.try(:arity) == 1 && t.call( self ) || t.try(:call)
      elsif t.is_a?(Proc)
        instance_eval(&t)
      else
        t
      end.to_s
    end

    # if localization is absent than block must be given
    send(enum_plural).localizations.merge!(
      localization_definitions.try(:with_indifferent_access) ||
        send(enum_plural).map do |k, _v|
          # little bit hackerish: instantiate object just with enum setup and then call its t_.. method which
          [k, Proc.new{ self.new({ enum_name => k }).send("t_#{enum_name}") }]
        end.to_h.with_indifferent_access
    )

    # hm.. lost myself here, why did I implement this method
    define_method "t_#{enum_name}=" do |new_val|
      send("#{enum_name}=", new_val)
    end

  end
end
Also aliased as: localize_enum
localize_enum( *args, &block )
Alias for: humanize_enum
translate_enum( *args, &block ) click to toggle source

Simple way to translate enum. It use either given scope as second argument, or generated activerecord.attributes.model_name_underscore.enum_name If block is given than no scopes are taken in consider

# File lib/enum_ext/humanize_helpers.rb, line 86
def translate_enum( *args, &block )
  enum_name = args.shift
  enum_plural = enum_name.to_s.pluralize
  t_scope = args.pop || "activerecord.attributes.#{self.name.underscore}.#{enum_plural}"

  if block_given?
    humanize_enum( enum_name, &block )
  else
    humanize_enum( enum_name, send(enum_plural).keys.map{|en| [ en, Proc.new{ I18n.t("#{t_scope}.#{en}") }] }.to_h )
  end
end