Module: PowerEnum::Enumerated::ClassMethods

Defined in:
lib/power_enum/enumerated.rb

Overview

Class level methods injected into ActiveRecord.

Instance Method Summary collapse

Instance Method Details

#acts_as_enumerated(options = {}) ⇒ Object

Declares the model as enumerated. See the README for detailed usage instructions.

Supported options

[:conditions] SQL search conditions [:order] SQL load order clause [:on_lookup_failure] Specifies the name of a class method to invoke when the [] method is unable to locate a BookingStatus record for arg. The default is the built-in :enforce_none which returns nil. There are also built-ins for :enforce_strict (raise and exception regardless of the type for arg), :enforce_strict_literals (raises an exception if the arg is a Integer or Symbol), :enforce_strict_ids (raises and exception if the arg is a Integer) and :enforce_strict_symbols (raises an exception if the arg is a Symbol). The purpose of the :on_lookup_failure option is that a) under some circumstances a lookup failure is a Bad Thing and action should be taken, therefore b) a fallback action should be easily configurable. You can also give it a lambda that takes in a single argument (The arg that was passed to []). [:name_column] Override for the 'name' column. By default, assumed to be 'name'. [:alias_name] By default, if a name column is not 'name', will create an alias of 'name' to the name_column attribute. Set this to false if you don't want this behavior. [:freeze_members] Specifies whether individual enum instances should be frozen on database load. By default, true in production. Can be either a lambda or a boolean.

Examples

====Example 1 class BookingStatus < ActiveRecord::Base acts_as_enumerated end

====Example 2 class BookingStatus < ActiveRecord::Base acts_as_enumerated :on_lookup_failure => :enforce_strict end

====Example 3 class BookingStatus < ActiveRecord::Base acts_as_enumerated :conditions => [:exclude => false], :order => 'created_at DESC', :on_lookup_failure => :lookup_failed, :name_column => :status_code

def self.lookup_failed(arg)
 logger.error("Invalid status code lookup #{arg.inspect}")
 nil
end

end

====Example 4 class BookingStatus < ActiveRecord::Base acts_as_enumerated :conditions => [:exclude => false], :order => 'created_at DESC', :on_lookup_failure => lambda { |arg| raise CustomError, "BookingStatus lookup failed; #arg" }, :name_column => :status_code, :freeze_members => true end



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/power_enum/enumerated.rb', line 79

def acts_as_enumerated(options = {})
  valid_keys = [:conditions, :order, :on_lookup_failure, :name_column, :alias_name, :freeze_members]
  options.assert_valid_keys(*valid_keys)

  valid_keys.each do |key|
    class_attribute "acts_enumerated_#{key.to_s}"
    if options.has_key?( key )
      self.send "acts_enumerated_#{key.to_s}=", options[key]
    end
  end

  self.acts_enumerated_name_column = get_name_column(options)

  unless self.is_a? PowerEnum::Enumerated::EnumClassMethods
    preserve_query_aliases
    extend_enum_class_methods( options )
  end
end

#acts_as_enumerated?Boolean

Returns false for ActiveRecord models that do not act as enumerated.

Returns:

  • (Boolean)


17
18
19
# File 'lib/power_enum/enumerated.rb', line 17

def acts_as_enumerated?
  false
end

#extend_enum_class_methods(options) ⇒ Object

Injects the class methods into model



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/power_enum/enumerated.rb', line 126

def extend_enum_class_methods(options) #:nodoc:

  extend PowerEnum::Enumerated::EnumClassMethods

  class_eval do
    include PowerEnum::Enumerated::EnumInstanceMethods

    before_save :enumeration_model_update
    before_destroy :enumeration_model_update
    validates acts_enumerated_name_column, :presence => true, :uniqueness => true
    validate :validate_enumeration_model_updates_permitted

    define_method :__enum_name__ do
      read_attribute(acts_enumerated_name_column).to_s
    end

    if should_alias_name?(options) && acts_enumerated_name_column != :name
      alias_method :name, :__enum_name__
    end
  end # class_eval

end

#get_name_column(options) ⇒ Object

Extracts the name column from options or gives the default



159
160
161
162
163
164
165
# File 'lib/power_enum/enumerated.rb', line 159

def get_name_column(options) #:nodoc:
  if options.has_key?(:name_column) && !options[:name_column].blank? then
    options[:name_column].to_s.to_sym
  else
    :name
  end
end

#preserve_query_aliasesObject

Rails 4 delegates all the finder methods to 'all'. PowerEnum overrides 'all'. Hence, the need to re-alias the query methods.



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/power_enum/enumerated.rb', line 100

def preserve_query_aliases
  class << self
    # I have to do the interesting hack below instead of using alias_method
    # because there's some sort of weirdness going on with how __all binds
    # to all in Ruby 2.0.
    __all = self.instance_method(:all)

    define_method(:__all) do
      __all.bind(self).call
    end

    # From ActiveRecord::Querying
    delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :to => :__all
    delegate :first_or_create, :first_or_create!, :first_or_initialize, :to => :__all
    delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, :to => :__all
    delegate :find_by, :find_by!, :to => :__all
    delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, :to => :__all
    delegate :find_each, :find_in_batches, :to => :__all
    delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins,
             :where, :preload, :eager_load, :includes, :from, :lock, :readonly,
             :having, :create_with, :uniq, :distinct, :references, :none, :unscope, :to => :__all
    delegate :count, :average, :minimum, :maximum, :sum, :calculate, :pluck, :ids, :to => :__all
  end
end

#should_alias_name?(options) ⇒ Boolean

Determines if the name column should be explicitly aliased

Returns:

  • (Boolean)


150
151
152
153
154
155
156
# File 'lib/power_enum/enumerated.rb', line 150

def should_alias_name?(options) #:nodoc:
  if options.has_key?(:alias_name) then
    options[:alias_name]
  else
    true
  end
end