Module: EnumX::DSL

Defined in:
lib/enum_x/dsl.rb

Overview

Mixin for any ActiveRecord or ActiveModel object to support enums.

Usage

First, make sure your model class includes EnumX::DSL:

include EnumX::DSL

Then, define any enum-like attribute using the #enum method. The best enum is always inferred. The following are identical:

enum :status, :statuses
enum :status, EnumX.statuses
enum :status, EnumX[:statuses]
enum :status

The latter infers the ‘statuses’ enum by default. If no applicable enum was found, an error is thrown.

Multi-enums

Specify the option :flags => true to allow the attribute to contain multiple enum values at once. The attribute will in essence become an array.

See Also:

Defined Under Namespace

Modules: ClassMethods Classes: FlagsSerializer, SingleSerializer

Class Method Summary collapse

Class Method Details

.define_mnemonics(target, attribute, enum) ⇒ Object

Mnemonics (single & multi)



349
350
351
352
353
354
355
356
357
# File 'lib/enum_x/dsl.rb', line 349

def self.define_mnemonics(target, attribute, enum)
  enum.values.each do |value|
    target.class_eval "      def \#{value}?\n        :\#{value} === \#{attribute}\n      end\n    RUBY\n  end\nend\n", __FILE__, __LINE__+1

.define_multi_reader(target, attribute) ⇒ Object

Multi enum reader & writer



321
322
323
324
325
326
327
328
329
330
331
# File 'lib/enum_x/dsl.rb', line 321

def self.define_multi_reader(target, attribute)
  define_reader target, attribute, "    enum = EnumX.find(self.class, :\#{attribute.to_s})\n    case value = %{read_value}\n    when nil then nil\n    when EnumX::ValueList then value\n    when Enumerable then EnumX::ValueList.new(enum, value)\n    else EnumX::ValueList.new(enum, [value])\n    end\n  RUBY\nend\n"

.define_multi_writer(target, attribute) ⇒ Object



333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/enum_x/dsl.rb', line 333

def self.define_multi_writer(target, attribute)
  define_writer target, attribute, "    enum = EnumX.find(self.class, :\#{attribute.to_s})\n    value = case value\n    when nil then nil\n    when EnumX::ValueList then value\n    when Enumerable then EnumX::ValueList.new(enum, value)\n    else EnumX::ValueList.new(enum, [value])\n    end\n    %{write_value}\n  RUBY\nend\n"

.define_reader(target, attribute, body) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Defines a generic attribute reader ActiveModel-like classes.



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/enum_x/dsl.rb', line 225

def self.define_reader(target, attribute, body)
  override = target.instance_methods.include?(attribute.to_sym)

  value_reader = case true
  when override
    "#{attribute}_without_enums"
  when target.instance_methods.include?(:read_attribute) || target.private_instance_methods.include?(:read_attribute)
    "read_attribute(:#{attribute})"
  else
    # We need a reader to fall back to.
    raise "cannot overwrite enum reader - no existing reader found"
  end

  body.gsub! '%{read_value}', value_reader

  if override
    target.class_eval "      def \#{attribute}_with_enums\n        \#{body}\n      end\n      alias_method_chain :\#{attribute}, :enums\n    RUBY\n  else\n    target.class_eval <<-RUBY, __FILE__, __LINE__+1\n      def \#{attribute}\n        \#{body}\n      end\n    RUBY\n  end\nend\n", __FILE__, __LINE__+1

.define_single_reader(target, attribute) ⇒ Object

Single enum reader & writer



293
294
295
296
297
298
299
300
301
302
303
# File 'lib/enum_x/dsl.rb', line 293

def self.define_single_reader(target, attribute)
  define_reader target, attribute, "    case value = %{read_value}\n    when EnumX::Value then value\n    when nil then nil\n    else\n      enum = EnumX.find(self.class, :\#{attribute.to_s.pluralize})\n      enum[value] || value\n    end\n  RUBY\nend\n"

.define_single_writer(target, attribute) ⇒ Object



305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/enum_x/dsl.rb', line 305

def self.define_single_writer(target, attribute)
  define_writer target, attribute, "    value = case value\n    when EnumX::Value then value\n    when nil then nil\n    else\n      enum = EnumX.find(self.class, :\#{attribute.to_s.pluralize})\n      enum[value] || value\n    end\n    %{write_value}\n  RUBY\nend\n"

.define_writer(target, attribute, body) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Defines a generic attribute writer ActiveModel-like classes.



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/enum_x/dsl.rb', line 258

def self.define_writer(target, attribute, body)
  method = :"#{attribute}="
  override = target.instance_methods.include?(method)

  value_writer = case true
  when override
    "self.#{attribute}_without_enums = value"
  when target.instance_methods.include?(:write_attribute) || target.private_instance_methods.include?(:write_attribute)
    "write_attribute :#{attribute}, value"
  else
    # We need a writer to fall back to.
    raise "cannot overwrite enum writer - no existing writer found"
  end

  body.gsub! '%{write_value}', value_writer

  if override
    target.class_eval "      def \#{attribute}_with_enums=(value)\n        \#{body}\n      end\n      alias_method_chain :\#{attribute}=, :enums\n    RUBY\n  else\n    target.class_eval <<-RUBY, __FILE__, __LINE__+1\n      def \#{attribute}=(value)\n        \#{body}\n      end\n    RUBY\n  end\nend\n", __FILE__, __LINE__+1

.included(target) ⇒ Object



30
31
32
# File 'lib/enum_x/dsl.rb', line 30

def self.included(target)
  target.extend ClassMethods
end