Module: EnumExt::HumanizeHelpers

Included in:
EnumExt
Defined in:
lib/enum_ext/humanize_helpers.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.define_superset_humanization_helpers(base_class, superset_name, enum_name) ⇒ Object

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



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# 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

Instance Method Details

#human_attribute_name(name, options = {}) ⇒ Object

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



101
102
103
104
# 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) ⇒ Object Also known as: localize_enum

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") }, ....  }


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# 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

#translate_enum(*args, &block) ⇒ Object

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



86
87
88
89
90
91
92
93
94
95
96
# 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