enumerated_attribute 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. data/.gitignore +16 -0
  2. data/CHANGELOG.rdoc +49 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +555 -0
  5. data/Rakefile +104 -0
  6. data/init.rb +1 -0
  7. data/lib/enumerated_attribute.rb +24 -0
  8. data/lib/enumerated_attribute/attribute.rb +78 -0
  9. data/lib/enumerated_attribute/attribute/arguments.rb +48 -0
  10. data/lib/enumerated_attribute/attribute/attribute_descriptor.rb +51 -0
  11. data/lib/enumerated_attribute/attribute/class_methods.rb +42 -0
  12. data/lib/enumerated_attribute/attribute/instance_methods.rb +96 -0
  13. data/lib/enumerated_attribute/integrations.rb +33 -0
  14. data/lib/enumerated_attribute/integrations/active_record.rb +109 -0
  15. data/lib/enumerated_attribute/integrations/datamapper.rb +6 -0
  16. data/lib/enumerated_attribute/integrations/default.rb +25 -0
  17. data/lib/enumerated_attribute/integrations/object.rb +47 -0
  18. data/lib/enumerated_attribute/method_definition_dsl.rb +142 -0
  19. data/lib/enumerated_attribute/rails_helpers.rb +97 -0
  20. data/lib/jeffp-enumerated_attribute.rb +1 -0
  21. data/spec/active_record/active_record_spec.rb +363 -0
  22. data/spec/active_record/association_test_classes.rb +40 -0
  23. data/spec/active_record/associations_spec.rb +130 -0
  24. data/spec/active_record/cfg.rb +6 -0
  25. data/spec/active_record/inheritance_classes.rb +19 -0
  26. data/spec/active_record/inheritance_spec.rb +60 -0
  27. data/spec/active_record/race_car.rb +15 -0
  28. data/spec/active_record/single_table_inheritance_spec.rb +0 -0
  29. data/spec/active_record/sti_classes.rb +10 -0
  30. data/spec/active_record/sti_spec.rb +41 -0
  31. data/spec/active_record/test_in_memory.rb +71 -0
  32. data/spec/car.rb +67 -0
  33. data/spec/cfg.rb +8 -0
  34. data/spec/inheritance_classes.rb +16 -0
  35. data/spec/inheritance_spec.rb +80 -0
  36. data/spec/new_and_method_missing_spec.rb +73 -0
  37. data/spec/plural.rb +8 -0
  38. data/spec/poro_spec.rb +397 -0
  39. data/spec/rails/README +243 -0
  40. data/spec/rails/Rakefile +10 -0
  41. data/spec/rails/app/controllers/application_controller.rb +10 -0
  42. data/spec/rails/app/controllers/form_test_controller.rb +38 -0
  43. data/spec/rails/app/helpers/application_helper.rb +3 -0
  44. data/spec/rails/app/helpers/form_test_helper.rb +2 -0
  45. data/spec/rails/app/models/user.rb +9 -0
  46. data/spec/rails/app/views/form_test/form.html.erb +1 -0
  47. data/spec/rails/app/views/form_test/form_for.html.erb +10 -0
  48. data/spec/rails/app/views/form_test/form_tag.html.erb +9 -0
  49. data/spec/rails/app/views/form_test/index.html.erb +6 -0
  50. data/spec/rails/app/views/layouts/application.html.erb +11 -0
  51. data/spec/rails/config/boot.rb +110 -0
  52. data/spec/rails/config/database.yml +22 -0
  53. data/spec/rails/config/environment.rb +45 -0
  54. data/spec/rails/config/environments/development.rb +17 -0
  55. data/spec/rails/config/environments/production.rb +28 -0
  56. data/spec/rails/config/environments/test.rb +28 -0
  57. data/spec/rails/config/initializers/backtrace_silencers.rb +7 -0
  58. data/spec/rails/config/initializers/inflections.rb +10 -0
  59. data/spec/rails/config/initializers/mime_types.rb +5 -0
  60. data/spec/rails/config/initializers/new_rails_defaults.rb +19 -0
  61. data/spec/rails/config/initializers/session_store.rb +15 -0
  62. data/spec/rails/config/locales/en.yml +5 -0
  63. data/spec/rails/config/routes.rb +43 -0
  64. data/spec/rails/db/development.sqlite3 +0 -0
  65. data/spec/rails/db/migrate/20090804230221_create_sessions.rb +16 -0
  66. data/spec/rails/db/migrate/20090804230546_create_users.rb +21 -0
  67. data/spec/rails/db/schema.rb +35 -0
  68. data/spec/rails/db/test.sqlite3 +0 -0
  69. data/spec/rails/public/404.html +30 -0
  70. data/spec/rails/public/422.html +30 -0
  71. data/spec/rails/public/500.html +30 -0
  72. data/spec/rails/public/favicon.ico +0 -0
  73. data/spec/rails/public/images/rails.png +0 -0
  74. data/spec/rails/public/index.html +275 -0
  75. data/spec/rails/public/javascripts/application.js +2 -0
  76. data/spec/rails/public/javascripts/controls.js +963 -0
  77. data/spec/rails/public/javascripts/dragdrop.js +973 -0
  78. data/spec/rails/public/javascripts/effects.js +1128 -0
  79. data/spec/rails/public/javascripts/prototype.js +4320 -0
  80. data/spec/rails/public/robots.txt +5 -0
  81. data/spec/rails/public/stylesheets/scaffold.css +54 -0
  82. data/spec/rails/script/about +4 -0
  83. data/spec/rails/script/autospec +6 -0
  84. data/spec/rails/script/console +3 -0
  85. data/spec/rails/script/dbconsole +3 -0
  86. data/spec/rails/script/destroy +3 -0
  87. data/spec/rails/script/generate +3 -0
  88. data/spec/rails/script/performance/benchmarker +3 -0
  89. data/spec/rails/script/performance/profiler +3 -0
  90. data/spec/rails/script/plugin +3 -0
  91. data/spec/rails/script/runner +3 -0
  92. data/spec/rails/script/server +3 -0
  93. data/spec/rails/script/spec +10 -0
  94. data/spec/rails/script/spec_server +9 -0
  95. data/spec/rails/spec/controllers/form_test_controller_spec.rb +41 -0
  96. data/spec/rails/spec/integrations/enum_select_spec.rb +75 -0
  97. data/spec/rails/spec/matchers.rb +12 -0
  98. data/spec/rails/spec/rcov.opts +2 -0
  99. data/spec/rails/spec/spec.opts +4 -0
  100. data/spec/rails/spec/spec_helper.rb +40 -0
  101. data/spec/rails/spec/views/form_test/form.html.erb_spec.rb +12 -0
  102. data/spec/rails/spec/views/form_test/form_for.html.erb_spec.rb +12 -0
  103. data/spec/rails/spec/views/form_test/form_tag.html.erb_spec.rb +12 -0
  104. data/spec/rcov.opts +2 -0
  105. data/spec/spec.opts +4 -0
  106. data/spec/tractor.rb +48 -0
  107. metadata +182 -0
data/Rakefile ADDED
@@ -0,0 +1,104 @@
1
+ #require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+ require 'rake/contrib/sshpublisher'
5
+ require 'gem_version'
6
+
7
+ spec = Gem::Specification.new do |s|
8
+ s.name = 'enumerated_attribute'
9
+ s.version = GemVersion.next_version
10
+ s.platform = Gem::Platform::RUBY
11
+ s.description = 'Enumerated model attributes and view helpers'
12
+ s.summary = 'Add enumerated attributes to your models and expose them in drop-down lists in your views'
13
+
14
+ s.add_dependency('meta_programming', '>= 0.2.1')
15
+
16
+ exclude_folders = 'spec/rails/{doc,lib,log,nbproject,tmp,vendor,test}'
17
+ exclude_files = FileList['**/*.log'] + FileList[exclude_folders+'/**/*'] + FileList[exclude_folders]
18
+ s.files = FileList['{examples,lib,tasks,spec}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc .gitignore) - exclude_files
19
+ s.require_path = 'lib'
20
+ s.has_rdoc = true
21
+ s.test_files = Dir['spec/*_spec.rb']
22
+
23
+ s.author = 'Jeff Patmon'
24
+ s.email = 'jpatmon@gmail.com'
25
+ s.homepage = 'http://github.com/jeffp/enumerated_attribute/tree/master'
26
+ end
27
+
28
+ require 'spec/version'
29
+ require 'spec/rake/spectask'
30
+
31
+ desc "Run specs"
32
+
33
+ namespace :spec do
34
+ task :default=>:all
35
+ Spec::Rake::SpecTask.new(:object) do |t|
36
+ t.spec_files = FileList['spec/*_spec.rb']
37
+ t.libs << 'lib' << 'spec'
38
+ t.rcov = false
39
+ t.spec_opts = ['--options', 'spec/spec.opts']
40
+ #t.rcov_dir = 'coverage'
41
+ #t.rcov_opts = ['--exclude', "kernel,load-diff-lcs\.rb,instance_exec\.rb,lib/spec.rb,lib/spec/runner.rb,^spec/*,bin/spec,examples,/gems,/Library/Ruby,\.autotest,#{ENV['GEM_HOME']}"]
42
+ end
43
+ =begin
44
+ Spec::Rake::SpecTask.new(:sub) do |t|
45
+ t.spec_files = FileList['spec/inheritance_spec.rb']
46
+ t.libs << 'lib' << 'spec'
47
+ t.rcov = false
48
+ t.spec_opts = ['--options', 'spec/spec.opts']
49
+ end
50
+ Spec::Rake::SpecTask.new(:poro) do |t|
51
+ t.spec_files = FileList['spec/poro_spec.rb']
52
+ t.libs << 'lib' << 'spec'
53
+ t.rcov = false
54
+ t.spec_opts = ['--options', 'spec/spec.opts']
55
+ end
56
+ =end
57
+ desc "Run ActiveRecord integration specs"
58
+ Spec::Rake::SpecTask.new(:ar) do |t|
59
+ t.spec_files = FileList['spec/active_record/*_spec.rb']
60
+ t.libs << 'lib' << 'spec/active_record'
61
+ t.spec_opts = ['--options', 'spec/spec.opts']
62
+ t.rcov = false
63
+ end
64
+ Spec::Rake::SpecTask.new(:forms) do |t|
65
+ t.spec_files = FileList['spec/rails/spec/integrations/*_spec.rb']
66
+ t.libs << 'lib' << 'spec/rails/spec'
67
+ t.spec_opts = ['--options', 'spec/spec.opts']
68
+ t.rcov = false
69
+ end
70
+ # Spec::Rake::SpecTask.new(:associations) do |t|
71
+ # t.spec_files = FileList['spec/active_record/associations_spec.rb']
72
+ # t.libs << 'lib' << 'spec/active_record'
73
+ # t.rcov = false
74
+ # end
75
+ desc "Run all specs"
76
+ task :all=>[:object, :ar, :forms]
77
+ end
78
+
79
+
80
+ desc "Generate documentation for the #{spec.name} plugin."
81
+ Rake::RDocTask.new(:rdoc) do |rdoc|
82
+ rdoc.rdoc_dir = 'rdoc'
83
+ rdoc.title = spec.name
84
+ #rdoc.template = '../rdoc_template.rb'
85
+ rdoc.options << '--line-numbers' << '--inline-source'
86
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
87
+ end
88
+
89
+ desc 'Generate a gemspec file.'
90
+ task :gemspec do
91
+ File.open("#{spec.name}.gemspec", 'w') do |f|
92
+ f.write spec.to_ruby
93
+ end
94
+ GemVersion.increment_version
95
+ GemVersion.commit_and_push
96
+ end
97
+
98
+ Rake::GemPackageTask.new(spec) do |p|
99
+ p.gem_spec = spec
100
+ p.need_tar = RUBY_PLATFORM =~ /mswin/ ? false : true
101
+ p.need_zip = true
102
+ end
103
+
104
+ Dir['tasks/**/*.rake'].each {|rake| load rake}
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'enumerated_attribute'
@@ -0,0 +1,24 @@
1
+ gem 'meta_programming', '>= 0.2.0'
2
+ require 'meta_programming'
3
+ require 'enumerated_attribute/attribute'
4
+
5
+ module EnumeratedAttribute
6
+
7
+ module MacroMethods
8
+
9
+ def enumerated_attribute(*args, &block)
10
+ class << self
11
+ include EnumeratedAttribute::Attribute
12
+ end
13
+ create_enumerated_attribute(*args, &block)
14
+ end
15
+ alias_method :enum_attr, :enumerated_attribute
16
+
17
+ end
18
+
19
+ end
20
+
21
+ Class.class_eval do
22
+ include EnumeratedAttribute::MacroMethods
23
+ end
24
+
@@ -0,0 +1,78 @@
1
+ require 'enumerated_attribute/attribute/attribute_descriptor'
2
+ require 'enumerated_attribute/attribute/arguments'
3
+ require 'enumerated_attribute/attribute/instance_methods'
4
+ require 'enumerated_attribute/attribute/class_methods'
5
+ require 'enumerated_attribute/method_definition_dsl'
6
+ require 'enumerated_attribute/integrations'
7
+ require 'enumerated_attribute/rails_helpers'
8
+ require 'ostruct'
9
+
10
+ module EnumeratedAttribute
11
+
12
+ class EnumeratedAttributeError < StandardError; end
13
+ class IntegrationError < EnumeratedAttributeError; end
14
+ class InvalidEnumeration < EnumeratedAttributeError; end
15
+ class InvalidDefinition < EnumeratedAttributeError; end
16
+ class AmbiguousMethod < EnumeratedAttributeError; end
17
+
18
+ module Attribute
19
+ private
20
+
21
+ def create_enumerated_attribute(*args, &block)
22
+ return if args.empty?
23
+ config = Arguments.parse_enum_attr_arguments(args)
24
+
25
+ class_eval do
26
+ @enumerated_attributes ||= {}
27
+ @enumerated_attributes[config.attr_symbol] = AttributeDescriptor.new(config.attr_symbol, config.enums, config.opts)
28
+
29
+ unless @integration_map
30
+ @integration_map = Integrations.find_integration_map(self)
31
+ @integration_map[:aliasing].each do |p|
32
+ alias_method(p.first, p.last)
33
+ end
34
+ include(EnumeratedAttribute::Integrations::Default)
35
+ include(@integration_map[:module]) if @integration_map[:module]
36
+
37
+ self.extend ClassMethods
38
+ include InstanceMethods
39
+ end
40
+ end
41
+
42
+ #create accessors
43
+ define_enumerated_attribute_reader_method(config.attr_symbol) unless (config.opts.key?(:reader) && !config.opts[:reader])
44
+ define_enumerated_attribute_writer_method(config.attr_symbol) unless (config.opts.key?(:writer) && !config.opts[:writer])
45
+ define_enumerated_attribute_new_method
46
+
47
+ #create state and action methods from block
48
+ config.initial_value = config.opts[:init] || config.initial_value
49
+ if block_given?
50
+ m = EnumeratedAttribute::MethodDefinitionDSL.new(self, self.enumerated_attributes(false)[config.attr_symbol]) #attr_name, enums)
51
+ m.instance_eval(&block)
52
+ config.initial_value = m.initial_value || config.initial_value
53
+ config.plural_name = m.pluralized_name || config.plural_name
54
+ config.decrementor = m.decrementor_name || config.decrementor
55
+ config.incrementor = m.incrementor_name || config.incrementor
56
+ end
57
+
58
+ #define the enum values accessor
59
+ class_eval do
60
+ @enumerated_attributes ||={}
61
+ @enumerated_attributes[config.attr_symbol].init_value = config.initial_value if config.initial_value
62
+
63
+ define_method(config.plural_name.to_sym) { self.class.enumerated_attributes[config.attr_symbol]}
64
+ define_method(config.incrementor.to_sym) do
65
+ z = self.class.enumerated_attributes[config.attr_symbol].enums
66
+ index = z.index(read_enumerated_attribute(config.attr_symbol))
67
+ write_enumerated_attribute(config.attr_symbol, z[index >= z.size-1 ? 0 : index+1])
68
+ end
69
+ define_method(config.decrementor.to_sym) do
70
+ z = self.class.enumerated_attributes[config.attr_symbol].enums
71
+ index = z.index(read_enumerated_attribute(config.attr_symbol))
72
+ write_enumerated_attribute(config.attr_symbol, z[index > 0 ? index-1 : z.size-1])
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,48 @@
1
+ module EnumeratedAttribute
2
+ module Attribute
3
+ module Arguments
4
+ def self.validate_enum_attr_arguments(config)
5
+ raise(InvalidDefinition, 'second argument of enumerated_attribute/enum_attr is not an array of symbols or strings representing the enum values', caller) if config.enums.empty?
6
+ end
7
+ def self.init_incrementor_decrementor_method_names(config)
8
+ config.incrementor = config.opts[:incrementor] || config.opts[:inc] || "#{config.attr_name}_next"
9
+ config.decrementor = config.opts[:decrementor] || config.opts[:dec] || "#{config.attr_name}_previous"
10
+ end
11
+ def self.init_plural_name(config)
12
+ config.plural_name = config.opts[:plural] || config.opts[:enums_accessor] || config.opts[:enums] || begin
13
+ case
14
+ when config.attr_name =~ /[aeiou]y$/
15
+ "#{config.attr_name}s"
16
+ when config.attr_name =~ /y$/
17
+ config.attr_name.sub(/y$/, 'ies')
18
+ when config.attr_name =~ /(sh|ch|x|s)$/
19
+ "#{config.attr_name}es"
20
+ else
21
+ "#{config.attr_name}s"
22
+ end
23
+ end
24
+ end
25
+ def self.process_enums_for_initial_value(config)
26
+ config.initial_value = nil
27
+ config.enums = config.enums.map{|v| (v =~ /^\^/ ? (config.initial_value ||= v[1, v.length-1].to_sym) : v.to_sym )}
28
+ end
29
+
30
+ def self.parse_enum_attr_arguments(args)
31
+ config = OpenStruct.new
32
+ config.attr_name = args[0].to_s
33
+ config.attr_symbol = config.attr_name.to_sym
34
+ config.enums = (args[1] && args[1].is_a?(Array) ? args[1] : [])
35
+ index = config.enums.empty? ? 1 : 2
36
+ config.opts = (args[index] && args[index].is_a?(Hash) ? args[index] : {})
37
+
38
+ validate_enum_attr_arguments(config)
39
+ init_plural_name(config)
40
+ init_incrementor_decrementor_method_names(config)
41
+ process_enums_for_initial_value(config)
42
+
43
+ config
44
+ end
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,51 @@
1
+
2
+ module EnumeratedAttribute
3
+ module Attribute
4
+ class AttributeDescriptor < Array
5
+ attr_reader :name
6
+ attr_accessor :init_value
7
+
8
+ def initialize(name, enums=[], opts={})
9
+ super enums
10
+ @name = name
11
+ @options = opts
12
+ @labels_hash = Hash[*self.collect{|e| [e, e.to_s.gsub(/_/, ' ').squeeze(' ').capitalize]}.flatten]
13
+ end
14
+
15
+ def allows_nil?
16
+ @options.key?(:nil) ? @options[:nil] : true
17
+ end
18
+ def allows_value?(value)
19
+ self.include?(value.to_sym)
20
+ end
21
+
22
+ def enums
23
+ self
24
+ end
25
+ def label(value)
26
+ @labels_hash[value]
27
+ end
28
+ def labels
29
+ @labels_array ||= self.map{|e| @labels_hash[e]}
30
+ end
31
+ def hash
32
+ @labels_hash
33
+ end
34
+ def select_options
35
+ @select_options ||= self.map{|e| [@labels_hash[e], e.to_s]}
36
+ end
37
+
38
+ def set_label(enum_value, label_string)
39
+ reset_labels
40
+ @labels_hash[enum_value.to_sym] = label_string
41
+ end
42
+
43
+ protected
44
+ def reset_labels
45
+ @labels_array = nil
46
+ @select_options = nil
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,42 @@
1
+ module EnumeratedAttribute
2
+ module Attribute
3
+ module ClassMethods
4
+ def enumerated_attributes(all=true)
5
+ return @enumerated_attributes unless all
6
+ return @all_enumerated_attributes_cache if @all_enumerated_attributes_cache
7
+ @all_enumerated_attributes_cache = @enumerated_attributes ? @enumerated_attributes.dup : {}
8
+ klass = self.superclass
9
+ while (klass)
10
+ if (klass.respond_to?(:enumerated_attributes))
11
+ if (sub_enums = klass.enumerated_attributes)
12
+ @all_enumerated_attributes_cache = sub_enums.merge @all_enumerated_attributes_cache
13
+ break
14
+ end
15
+ end
16
+ klass = klass.superclass
17
+ end
18
+ @all_enumerated_attributes_cache
19
+ end
20
+
21
+ def has_enumerated_attribute?(name)
22
+ !name.nil? && !!self.enumerated_attributes.key?(name.to_sym)
23
+ end
24
+ def enumerated_attribute_allows_nil?(name)
25
+ (descriptor = self.enumerated_attributes[name.to_sym]) && descriptor.allows_nil?
26
+ end
27
+ def enumerated_attribute_allows_value?(name, value)
28
+ return (false) unless (descriptor = self.enumerated_attributes[name.to_sym])
29
+ return descriptor.allows_nil? if (value == nil || value == '')
30
+ descriptor.allows_value?(value)
31
+ end
32
+
33
+ def define_enumerated_attribute_custom_method(symbol, attr_name, value, negated)
34
+ define_method symbol do
35
+ ival = read_enumerated_attribute(attr_name)
36
+ negated ? ival != value : ival == value
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,96 @@
1
+ module EnumeratedAttribute
2
+ module Attribute
3
+ module InstanceMethods
4
+ def self.included(base)
5
+
6
+ method_missing_suffix = "enumerated_attribute_#{base.name}_#{base.hash}".to_sym
7
+ define_method("method_missing_with_#{method_missing_suffix}") do |methId, *args|
8
+ return self.__send__(methId) if define_enumerated_attribute_dynamic_method(methId)
9
+ self.__send__("method_missing_without_#{method_missing_suffix}", methId, *args)
10
+ end
11
+
12
+ respond_to_suffix = "enumerated_attribute_#{base.name}_#{base.hash}".to_sym
13
+ base.class_eval %{
14
+ def respond_to_with_#{respond_to_suffix}?(method, include_private=false)
15
+ self.respond_to_without_#{respond_to_suffix}?(method, include_private) ||
16
+ (!!parse_dynamic_method_parts!(method.to_s) rescue false)
17
+ end
18
+ }
19
+
20
+ base.safe_alias_method_chain :method_missing, method_missing_suffix
21
+ base.safe_alias_method_chain :respond_to?, respond_to_suffix
22
+
23
+ end
24
+
25
+ def enums(attr)
26
+ self.class.enumerated_attributes[attr.to_sym]
27
+ end
28
+
29
+
30
+ def initialize_enumerated_attributes(only_if_nil = false)
31
+ self.class.enumerated_attributes.each do |k,v|
32
+ self.write_enumerated_attribute(k, v.init_value) unless (only_if_nil && read_enumerated_attribute(k) != nil)
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def parse_dynamic_method_parts!(meth_name)
39
+ return(nil) unless meth_name[-1, 1] == '?'
40
+
41
+ middle = meth_name.chop #remove the ?
42
+
43
+ attr = nil
44
+ self.class.enumerated_attributes.keys.each do |name|
45
+ if middle.sub!(Regexp.new("^"+name.to_s), "")
46
+ attr = name; break
47
+ end
48
+ end
49
+
50
+ value = nil
51
+ attr_sym = attr ? attr.to_sym : nil
52
+ if (descriptor = self.class.enumerated_attributes[attr_sym])
53
+ descriptor.enums.each do |v|
54
+ if middle.sub!(Regexp.new(v.to_s+"$"), "")
55
+ value = v; break
56
+ end
57
+ end
58
+ else
59
+ #search through enum values one at time and identify any ambiguities
60
+ self.class.enumerated_attributes.each do |attr_key,descriptor|
61
+ descriptor.enums.each do|v|
62
+ if middle.match(v.to_s+"$")
63
+ raise(AmbiguousMethod, meth_name+" is ambiguous, use something like "+attr_sym.to_s+(middle[0,1]=='_'? '' : '_')+middle+"? or "+attr_key.to_s+(middle[0,1]=='_'? '' : '_')+middle+"?", caller) if attr_sym
64
+ attr_sym = attr_key
65
+ value = v
66
+ end
67
+ end
68
+ end
69
+ return (nil) unless attr_sym
70
+ attr = attr_sym.to_s
71
+ middle.sub!(Regexp.new(value.to_s+"$"), "")
72
+ end
73
+
74
+ unless value #check for nil?
75
+ return (nil) unless middle.sub!(Regexp.new('nil$'), "")
76
+ value = nil
77
+ end
78
+
79
+ [attr, middle, value]
80
+ end
81
+
82
+ def define_enumerated_attribute_dynamic_method(methId)
83
+ meth_name = methId.id2name
84
+ parts = parse_dynamic_method_parts!(meth_name)
85
+ return(false) unless parts
86
+
87
+ negated = !!parts[1].downcase.match(/(^|_)not_/)
88
+ value = parts[2] ? parts[2].to_sym : nil
89
+ self.class.define_enumerated_attribute_custom_method(methId, parts[0], value, negated)
90
+
91
+ true
92
+ end
93
+
94
+ end
95
+ end
96
+ end