Module: PowerEnum::HasEnumerated::ClassMethods

Defined in:
lib/power_enum/has_enumerated.rb

Overview

Class-level behavior injected into ActiveRecord to support has_enumerated

Instance Method Summary collapse

Instance Method Details

#enumerated_attributesObject

Returns a list of all the attributes on the ActiveRecord model which are enumerated.



18
19
20
# File 'lib/power_enum/has_enumerated.rb', line 18

def enumerated_attributes
  @enumerated_attributes ||= []
end

#has_enumerated(part_id, options = {}) ⇒ Object

Defines an enumerated attribute with the given attribute_name on the model. Also accepts a hash of options as an optional second argument.

Supported options

[:class_name] Name of the enum class. By default it is the camelized version of the has_enumerated attribute. [:foreign_key] Explicitly set the foreign key column. By default it's assumed to be your_enumerated_attribute_name_id. [:on_lookup_failure] The :on_lookup_failure option in has_enumerated is there because you may want to create an error handler for situations where the argument passed to status=(arg) is invalid. By default, an invalid value will cause an ArgumentError to be raised. Since this may not be optimal in your situation, you can do one of three things:

1) You can set it to 'validation_error'.  In this case, the invalid value will be cached and returned on
subsequent lookups, but the model will fail validation.
2) You can specify an instance method to be called in the case of a lookup failure. The method signature is
as follows:
<tt>your_lookup_handler(operation, attribute_name, name_foreign_key, acts_enumerated_class_name, lookup_value)</tt>
The 'operation' arg will be either :read or :write.  In the case of :read you are expected to return
something or raise an exception, while in the case of a :write you don't have to return anything.  Note that
there's enough information in the method signature that you can specify one method to handle all lookup
failures for all has_enumerated fields if you happen to have more than one defined in your model.
'NOTE': A nil is always considered to be a valid value for status=(arg) since it's assumed you're trying to
null out the foreign key. The :on_lookup_failure method will be bypassed.
3) You can give it a lambda function.  In that case, the lambda needs to accept the ActiveRecord model as
its first argument, with the rest of the arguments being identical to the signature of the lookup handler
instance method.

[:permit_empty_name] Setting this to 'true' disables automatic conversion of empty strings to nil. Default is 'false'. [:default] Setting this option will generate an after_initialize callback to set a default value on the attribute unless a non-nil one already exists. [:create_scope] Setting this option to 'false' will disable automatically creating 'with_enum_attribute' and 'exclude_enum_attribute' scope.

Example

class Booking < ActiveRecord::Base has_enumerated :status, :class_name => 'BookingStatus', :foreign_key => 'status_id', :on_lookup_failure => :optional_instance_method, :permit_empty_name => true, :default => :unconfirmed, :create_cope => false end

Example 2

class Booking < ActiveRecord::Base has_enumerated :booking_status, :class_name => 'BookingStatus', :foreign_key => 'status_id', :on_lookup_failure => lambda{ |record, op, attr, fk, cl_name, value| # handle lookup failure } end



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/power_enum/has_enumerated.rb', line 86

def has_enumerated(part_id, options = {})
  options.assert_valid_keys(:class_name,
                            :foreign_key,
                            :on_lookup_failure,
                            :permit_empty_name,
                            :default,
                            :create_scope)

  # Add a reflection for the enumerated attribute.
  reflection = create_ar_reflection(part_id, options)

  attribute_name   = part_id.to_s
  class_name       = reflection.class_name
  foreign_key      = reflection.foreign_key
  failure_opt      = options[:on_lookup_failure]
  allow_empty_name = options[:permit_empty_name]
  create_scope     = options[:create_scope]

  failure_handler = get_lookup_failure_handler(failure_opt)

  class_attribute "has_enumerated_#{attribute_name}_error_handler"
  self.send("has_enumerated_#{attribute_name}_error_handler=", failure_handler)

  define_enum_accessor attribute_name, class_name, foreign_key, failure_handler
  define_enum_writer attribute_name, class_name, foreign_key, failure_handler, allow_empty_name

  if failure_opt.to_s == 'validation_error'
    define_validation_error(attribute_name)
  end

  enumerated_attributes << attribute_name

  if options.has_key?(:default)
    define_default_enum_value(attribute_name, options[:default])
  end

  unless create_scope == false
    define_enum_scope(attribute_name, class_name, foreign_key)
  end

end

#has_enumerated?(attribute) ⇒ Boolean

Returns true if attribute is an enumerated attribute, false otherwise.

Returns:

  • (Boolean)


23
24
25
26
# File 'lib/power_enum/has_enumerated.rb', line 23

def has_enumerated?(attribute)
  return false if attribute.nil?
  enumerated_attributes.include? attribute.to_s
end