Module: EnumExt
- Defined in:
- lib/enum_ext.rb,
lib/enum_ext/version.rb
Overview
Let’s assume we have model Request with enum status, and we have model Order with requests like this: class Request
extend EnumExt
belongs_to :order
enum status: [ :in_cart, :waiting_for_payment, :payed, :ready_for_shipment, :on_delivery, :delivered ]
end
class Order
has_many :requests
end
Constant Summary collapse
- VERSION =
"0.1.5"
Instance Method Summary collapse
-
#ext_enum_sets(enum_name, options) ⇒ Object
Rem: ext_enum_sets can be called twice defining a superpositoin of already defined sets: class Request …
-
#localize_enum(enum_name, localizations) ⇒ Object
if you need some substitution you can go like this localize_enum :status, { .. delivered: “Delivered at: %date” } request.delivered! request.t_status % Time.now.to_s # >> Delivered at: 05.02.2016.
-
#mass_assign_enum(*options) ⇒ Object
association_relation: true - Order.first.requests.scope.new_stat! - works but it wouldn’t works without ‘scope’ part! If you want to use it without ‘scope’ you may do it this way: class Request …
Instance Method Details
#ext_enum_sets(enum_name, options) ⇒ Object
Rem:
ext_enum_sets can be called twice defining a superpositoin of already defined sets:
class Request
...
ext_enum_sets (... first time call )
ext_enum_sets :status, {
already_payed: ( [:payed] | delivery_set_statuses ),
outside_wharehouse: ( delivery_set_statuses - in_warehouse_statuses )... any other array operations like &, + and so can be used
}
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/enum_ext.rb', line 112 def ext_enum_sets( enum_name, ) self.instance_eval do .each do |set_name, enum_vals| scope set_name, -> { where( enum_name => self.send( enum_name.to_s.pluralize ).slice( *enum_vals.map(&:to_s) ).values ) } define_singleton_method( "#{set_name}_#{enum_name.to_s.pluralize}" ) do enum_vals end define_method "#{set_name}?" do self.send(enum_name) && ( enum_vals.include?( self.send(enum_name) ) || enum_vals.include?( self.send(enum_name).to_sym )) end end scope "with_#{enum_name.to_s.pluralize}", -> (sets_arr) { where( enum_name => self.send( enum_name.to_s.pluralize ).slice( *sets_arr.map{|set_name| self.try( "#{set_name}_#{enum_name.to_s.pluralize}" ) || set_name }.flatten.uniq.map(&:to_s) ).values ) } unless respond_to?("with_#{enum_name.to_s.pluralize}") scope "without_#{enum_name.to_s.pluralize}", -> (sets_arr) { where.not( id: self.send("with_#{enum_name.to_s.pluralize}", sets_arr) ) } unless respond_to?("without_#{enum_name.to_s.pluralize}") end end |
#localize_enum(enum_name, localizations) ⇒ Object
if you need some substitution you can go like this
localize_enum :status, {
..
delivered: "Delivered at: %{date}"
}
request.delivered!
request.t_status % {date: Time.now.to_s} # >> Delivered at: 05.02.2016
Using in select:
f.select :status, Request.t_statuses.invert.to_a
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/enum_ext.rb', line 54 def localize_enum( enum_name, localizations ) self.instance_eval do define_singleton_method( "t_#{enum_name.to_s.pluralize}" ) do localizations.try(:with_indifferent_access) || localizations end define_method "t_#{enum_name}" do t = localizations.try(:with_indifferent_access)[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 end end |
#mass_assign_enum(*options) ⇒ Object
association_relation: true - Order.first.requests.scope.new_stat! - works but it wouldn’t works without ‘scope’ part! If you want to use it without ‘scope’ you may do it this way: class Request
...
mass_assign_enum( :status, association_relation: false )
end class Order
has_many :requests, extend: Request::MassAssignEnum
end
Order.first.requests.respond_to?(:in_cart!) # >> true
Rem2: you can mass-assign more than one enum ::MassAssignEnum module will contain mass assign for both. It will break nothing since all enum name must be uniq across model
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/enum_ext.rb', line 186 def mass_assign_enum( * ) = ([-1].is_a?(Hash) && .pop || {relation: true, association_relation: true} ).with_indifferent_access enums_names = enums_names.each do |enum_name| enum_vals = self.send( enum_name.to_s.pluralize ) mass_ass_module = ( defined?(self::MassAssignEnum) && self::MassAssignEnum || Module.new ) mass_ass_module.instance_eval do enum_vals.keys.each do |enum_el| define_method( "#{enum_el}!" ) do self.update_all( {enum_name => enum_vals[enum_el]}.merge( self.column_names.include?('updated_at') ? {updated_at: Time.now} : {} )) end end end self.const_set( :MassAssignEnum, mass_ass_module ) unless defined?(self::MassAssignEnum) self::ActiveRecord_Relation.include( self::MassAssignEnum ) if [:relation] self::ActiveRecord_AssociationRelation.include( self::MassAssignEnum ) if [:association_relation] end end |