module EnumExt::HumanizeHelpers
Public Class Methods
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
is redefined for automation like this: p #{object.class.human_attribute_name( attr_name )}: p object.send(attr_name)
# 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
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
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