module PowerEnum::HasEnumerated::ClassMethods
Class-level behavior injected into ActiveRecord
to support has_enumerated
Public Instance Methods
Source
# File lib/power_enum/has_enumerated.rb, line 18 def enumerated_attributes @enumerated_attributes ||= [] end
Returns a list of all the attributes on the ActiveRecord
model which are enumerated.
Source
# 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
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 tonull 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
Source
# 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
Returns true
if attribute
is an enumerated attribute, false
otherwise.
Private Instance Methods
Source
# File lib/power_enum/has_enumerated.rb, line 131 def create_ar_reflection(part_id, options) reflection = PowerEnum::Reflection::EnumerationReflection.new(part_id, options, self) self._reflections = self._reflections.merge(part_id.to_s => reflection) reflection end
Creates the ActiveRecord
reflection