Refactored Mongoid::Enum::ClassMethods for readability

This commit is contained in:
Nicholas Bruning 2014-03-17 23:35:39 +11:00
parent 9144fab09a
commit d4280d3eca

View File

@ -5,30 +5,53 @@ module Mongoid
module Enum module Enum
extend ActiveSupport::Concern extend ActiveSupport::Concern
module ClassMethods module ClassMethods
def enum(name, values, options = {}) def enum(name, values, options = {})
field_name = :"_#{name}" field_name = :"_#{name}"
const_name = name.to_s.upcase options = default_options(values).merge(options)
multiple = options[:multiple] || false
default = options[:default].nil? && values.first || options[:default]
required = options[:required].nil? || options[:required]
validate = options[:validate].nil? || options[:validate]
const_set const_name, values set_values_constant name, values
type = multiple && Array || Symbol create_field field_name, options
field field_name, :type => type, :default => default
alias_attribute name, field_name alias_attribute name, field_name
if multiple && validate create_validations field_name, values, options
validates field_name, :'mongoid/enum/validators/multiple' => { :in => values, :allow_nil => !required } define_value_scopes_and_accessors field_name, values, options
elsif validate
validates field_name, :inclusion => {:in => values}, :allow_nil => !required
end end
private
def default_options(values)
{
:multiple => false,
:default => values.first,
:required => true,
:validate => true
}
end
def set_values_constant(name, values)
const_name = name.to_s.upcase
const_set const_name, values
end
def create_field(field_name, options)
type = options[:multiple] && Array || Symbol
field field_name, :type => type, :default => options[:default]
end
def create_validations(field_name, values, options)
if options[:multiple] && options[:validate]
validates field_name, :'mongoid/enum/validators/multiple' => { :in => values, :allow_nil => !options[:required] }
elsif validate
validates field_name, :inclusion => {:in => values}, :allow_nil => !options[:required]
end
end
def define_value_scopes_and_accessors(field_name, values, options)
values.each do |value| values.each do |value|
scope value, where(field_name => value) scope value, where(field_name => value)
if multiple if options[:multiple]
class_eval "def #{value}?() self.#{field_name}.include?(:#{value}) end" class_eval "def #{value}?() self.#{field_name}.include?(:#{value}) end"
class_eval "def #{value}!() update_attributes! :#{field_name} => (self.#{field_name} || []) + [:#{value}] end" class_eval "def #{value}!() update_attributes! :#{field_name} => (self.#{field_name} || []) + [:#{value}] end"
else else