Module: EnumX::DSL::ClassMethods
- Defined in:
- lib/enum_x/dsl.rb
Overview
DSL methods
Instance Method Summary collapse
-
#enum(name, [enum], validation_options = {}) ⇒ Object
Defines an enum for an attribute.
Instance Method Details
#enum(name, [enum], validation_options = {}) ⇒ Object
Defines an enum for an attribute. This works on ActiveRecord objects, but also on other objects. However, for non-ActiveRecord objects, make sure that the underlying attribute already exists.
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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/enum_x/dsl.rb', line 89 def enum(attribute, *args) = args. enum = args.shift raise ArgumentError, "too many arguments (2..3 expected)" if args.length > 0 flags = .delete(:flags) mnemonics = .delete(:mnemonics) # Determine the default name of the enum, and the name of the class-level enum reader. enum_reader_name = if flags # The attribute is already specified in the plural form (enum :statuses). attribute.to_s else # The attribute is specified in the singular form - pluralize it (enum :status). attribute.to_s.pluralize end enum = case enum_opt = enum when nil then EnumX[enum_reader_name] when EnumX then enum when Symbol, String then EnumX[enum] when Enumerable name = if self.name "#{self.name.demodulize.underscore}_#{enum_reader_name}" else # Anonymous class - use just the attribute name with an underscore in front of it. "_#{enum_reader_name}" end EnumX.new(name, enum) end raise ArgumentError, "cannot find enum #{(enum_opt || enum_reader_name).inspect}" unless enum # Define a shorthand enum accessor method. unless respond_to?(enum_reader_name) # Regular class. As the class may be inherited, make sure to try superclasses as well. class_eval "def self.\#{enum_reader_name}\n@\#{enum_reader_name} ||= if superclass.respond_to?(:\#{enum_reader_name})\nsuperclass.\#{enum_reader_name}\nend\nend\n", __FILE__, __LINE__+1 end # Store the enum on this class. instance_variable_set "@#{enum_reader_name}", enum if flags # Define a flags enum. # Validation if [:validation] != false .assert_valid_keys :allow_blank if [:allow_blank] != false class_eval "validates_each :\#{attribute} do |record, attribute, value|\nif value.present?\nvalue = [ value ] unless value.is_a?(Enumerable)\nif not_included_value = value.find{ |v| !enum.values.include?(v) }\nrecord.errors.add attribute, :inclusion, :value => not_included_value\nend\nend\nend\n", __FILE__, __LINE__+1 else class_eval "validates_each :\#{attribute} do |record, attribute, value|\nvalue = [ value ] unless value.is_a?(Enumerable) || value.nil?\nif value.blank?\nrecord.errors.add attribute, :blank\nelsif not_included_value = value.find{ |v| !enum.values.include?(v) }\nrecord.errors.add attribute, :inclusion, :value => not_included_value\nend\nend\n", __FILE__, __LINE__+1 end end # Serialize the value if this is an ActiveRecord class AND if the database actually contains # this column. if defined?(ActiveRecord) && self < ActiveRecord::Base && self.column_names.include?(attribute.to_s) serialize attribute, FlagsSerializer.new(enum) end # Provide a customized reader. DSL.define_multi_reader self, attribute DSL.define_multi_writer self, attribute # Provide two Squeel sifters. if respond_to?(:sifter) class_eval "sifter(:\#{attribute}_include) { |value| instance_eval('\#{attribute}') =~ \"%|\\\#{value}|%\" }\nsifter(:\#{attribute}_exclude) { |value| instance_eval('\#{attribute}') !~ \"%|\\\#{value}|%\" }\n", __FILE__, __LINE__+1 end else # Define a single enum. # Validation if [:validation] != false # Provide validations. = .merge(:in => enum.values) [:allow_blank] = true unless .key?(:allow_blank) validates_inclusion_of attribute, end # Serialize the value if this is an ActiveRecord class AND if the database actually contains # this column. if defined?(ActiveRecord) && self < ActiveRecord::Base && self.column_names.include?(attribute.to_s) serialize attribute, SingleSerializer.new(enum) end # Provide a customized reader. DSL.define_single_reader self, attribute DSL.define_single_writer self, attribute end # Provide mnemonics if requested DSL.define_mnemonics self, attribute, enum if mnemonics end |