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.
- data/.gitignore +16 -0
- data/CHANGELOG.rdoc +49 -0
- data/LICENSE +20 -0
- data/README.rdoc +555 -0
- data/Rakefile +104 -0
- data/init.rb +1 -0
- data/lib/enumerated_attribute.rb +24 -0
- data/lib/enumerated_attribute/attribute.rb +78 -0
- data/lib/enumerated_attribute/attribute/arguments.rb +48 -0
- data/lib/enumerated_attribute/attribute/attribute_descriptor.rb +51 -0
- data/lib/enumerated_attribute/attribute/class_methods.rb +42 -0
- data/lib/enumerated_attribute/attribute/instance_methods.rb +96 -0
- data/lib/enumerated_attribute/integrations.rb +33 -0
- data/lib/enumerated_attribute/integrations/active_record.rb +109 -0
- data/lib/enumerated_attribute/integrations/datamapper.rb +6 -0
- data/lib/enumerated_attribute/integrations/default.rb +25 -0
- data/lib/enumerated_attribute/integrations/object.rb +47 -0
- data/lib/enumerated_attribute/method_definition_dsl.rb +142 -0
- data/lib/enumerated_attribute/rails_helpers.rb +97 -0
- data/lib/jeffp-enumerated_attribute.rb +1 -0
- data/spec/active_record/active_record_spec.rb +363 -0
- data/spec/active_record/association_test_classes.rb +40 -0
- data/spec/active_record/associations_spec.rb +130 -0
- data/spec/active_record/cfg.rb +6 -0
- data/spec/active_record/inheritance_classes.rb +19 -0
- data/spec/active_record/inheritance_spec.rb +60 -0
- data/spec/active_record/race_car.rb +15 -0
- data/spec/active_record/single_table_inheritance_spec.rb +0 -0
- data/spec/active_record/sti_classes.rb +10 -0
- data/spec/active_record/sti_spec.rb +41 -0
- data/spec/active_record/test_in_memory.rb +71 -0
- data/spec/car.rb +67 -0
- data/spec/cfg.rb +8 -0
- data/spec/inheritance_classes.rb +16 -0
- data/spec/inheritance_spec.rb +80 -0
- data/spec/new_and_method_missing_spec.rb +73 -0
- data/spec/plural.rb +8 -0
- data/spec/poro_spec.rb +397 -0
- data/spec/rails/README +243 -0
- data/spec/rails/Rakefile +10 -0
- data/spec/rails/app/controllers/application_controller.rb +10 -0
- data/spec/rails/app/controllers/form_test_controller.rb +38 -0
- data/spec/rails/app/helpers/application_helper.rb +3 -0
- data/spec/rails/app/helpers/form_test_helper.rb +2 -0
- data/spec/rails/app/models/user.rb +9 -0
- data/spec/rails/app/views/form_test/form.html.erb +1 -0
- data/spec/rails/app/views/form_test/form_for.html.erb +10 -0
- data/spec/rails/app/views/form_test/form_tag.html.erb +9 -0
- data/spec/rails/app/views/form_test/index.html.erb +6 -0
- data/spec/rails/app/views/layouts/application.html.erb +11 -0
- data/spec/rails/config/boot.rb +110 -0
- data/spec/rails/config/database.yml +22 -0
- data/spec/rails/config/environment.rb +45 -0
- data/spec/rails/config/environments/development.rb +17 -0
- data/spec/rails/config/environments/production.rb +28 -0
- data/spec/rails/config/environments/test.rb +28 -0
- data/spec/rails/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails/config/initializers/inflections.rb +10 -0
- data/spec/rails/config/initializers/mime_types.rb +5 -0
- data/spec/rails/config/initializers/new_rails_defaults.rb +19 -0
- data/spec/rails/config/initializers/session_store.rb +15 -0
- data/spec/rails/config/locales/en.yml +5 -0
- data/spec/rails/config/routes.rb +43 -0
- data/spec/rails/db/development.sqlite3 +0 -0
- data/spec/rails/db/migrate/20090804230221_create_sessions.rb +16 -0
- data/spec/rails/db/migrate/20090804230546_create_users.rb +21 -0
- data/spec/rails/db/schema.rb +35 -0
- data/spec/rails/db/test.sqlite3 +0 -0
- data/spec/rails/public/404.html +30 -0
- data/spec/rails/public/422.html +30 -0
- data/spec/rails/public/500.html +30 -0
- data/spec/rails/public/favicon.ico +0 -0
- data/spec/rails/public/images/rails.png +0 -0
- data/spec/rails/public/index.html +275 -0
- data/spec/rails/public/javascripts/application.js +2 -0
- data/spec/rails/public/javascripts/controls.js +963 -0
- data/spec/rails/public/javascripts/dragdrop.js +973 -0
- data/spec/rails/public/javascripts/effects.js +1128 -0
- data/spec/rails/public/javascripts/prototype.js +4320 -0
- data/spec/rails/public/robots.txt +5 -0
- data/spec/rails/public/stylesheets/scaffold.css +54 -0
- data/spec/rails/script/about +4 -0
- data/spec/rails/script/autospec +6 -0
- data/spec/rails/script/console +3 -0
- data/spec/rails/script/dbconsole +3 -0
- data/spec/rails/script/destroy +3 -0
- data/spec/rails/script/generate +3 -0
- data/spec/rails/script/performance/benchmarker +3 -0
- data/spec/rails/script/performance/profiler +3 -0
- data/spec/rails/script/plugin +3 -0
- data/spec/rails/script/runner +3 -0
- data/spec/rails/script/server +3 -0
- data/spec/rails/script/spec +10 -0
- data/spec/rails/script/spec_server +9 -0
- data/spec/rails/spec/controllers/form_test_controller_spec.rb +41 -0
- data/spec/rails/spec/integrations/enum_select_spec.rb +75 -0
- data/spec/rails/spec/matchers.rb +12 -0
- data/spec/rails/spec/rcov.opts +2 -0
- data/spec/rails/spec/spec.opts +4 -0
- data/spec/rails/spec/spec_helper.rb +40 -0
- data/spec/rails/spec/views/form_test/form.html.erb_spec.rb +12 -0
- data/spec/rails/spec/views/form_test/form_for.html.erb_spec.rb +12 -0
- data/spec/rails/spec/views/form_test/form_tag.html.erb_spec.rb +12 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/spec/tractor.rb +48 -0
- metadata +182 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'enumerated_attribute/integrations/active_record'
|
|
2
|
+
require 'enumerated_attribute/integrations/object'
|
|
3
|
+
require 'enumerated_attribute/integrations/datamapper'
|
|
4
|
+
require 'enumerated_attribute/integrations/default'
|
|
5
|
+
|
|
6
|
+
module EnumeratedAttribute
|
|
7
|
+
module Integrations
|
|
8
|
+
|
|
9
|
+
@@integration_map = {}
|
|
10
|
+
|
|
11
|
+
def self.add_integration_map(base_klass_name, module_object, aliasing_array=[])
|
|
12
|
+
@@integration_map[base_klass_name] = {:module=>module_object, :aliasing=>aliasing_array}
|
|
13
|
+
end
|
|
14
|
+
class << self
|
|
15
|
+
alias_method(:add, :add_integration_map)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#included mappings
|
|
19
|
+
add('Object', EnumeratedAttribute::Integrations::Object)
|
|
20
|
+
add('ActiveRecord::Base', EnumeratedAttribute::Integrations::ActiveRecord)
|
|
21
|
+
|
|
22
|
+
def self.find_integration_map(klass)
|
|
23
|
+
path = "#{klass}"
|
|
24
|
+
begin
|
|
25
|
+
return @@integration_map[klass.to_s] if @@integration_map.key?(klass.to_s)
|
|
26
|
+
klass = klass.superclass
|
|
27
|
+
path << " < #{klass}"
|
|
28
|
+
end while klass
|
|
29
|
+
raise EnumeratedAttribute::IntegrationError, "Unable to find integration for class hierarchy '#{path}'", caller
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
module EnumeratedAttribute
|
|
2
|
+
module Integrations
|
|
3
|
+
|
|
4
|
+
module ActiveRecord
|
|
5
|
+
def self.included(klass)
|
|
6
|
+
klass.extend(ClassMethods)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def write_enumerated_attribute(name, val)
|
|
10
|
+
name = name.to_s
|
|
11
|
+
return write_attribute(name, val) unless self.class.has_enumerated_attribute?(name)
|
|
12
|
+
val = nil if val == ''
|
|
13
|
+
val_str = val.to_s if val
|
|
14
|
+
val_sym = val.to_sym if val
|
|
15
|
+
unless self.class.enumerated_attribute_allows_value?(name, val_sym)
|
|
16
|
+
raise(InvalidEnumeration, "nil is not allowed on '#{name}' attribute, set :nil=>true option", caller) unless val
|
|
17
|
+
raise(InvalidEnumeration, ":#{val_str} is not a defined enumeration value for the '#{name}' attribute", caller)
|
|
18
|
+
end
|
|
19
|
+
return instance_variable_set('@'+name, val_sym) unless self.has_attribute?(name)
|
|
20
|
+
write_attribute(name, val_str)
|
|
21
|
+
val_sym
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def read_enumerated_attribute(name)
|
|
25
|
+
name = name.to_s
|
|
26
|
+
#if not enumerated - let active record handle it
|
|
27
|
+
return read_attribute(name) unless self.class.has_enumerated_attribute?(name)
|
|
28
|
+
#if enumerated, is it an active record attribute, if not, the value is stored in an instance variable
|
|
29
|
+
name_sym = name.to_sym
|
|
30
|
+
return instance_variable_get('@'+name) unless self.has_attribute?(name)
|
|
31
|
+
#this is an enumerated active record attribute
|
|
32
|
+
val = read_attribute(name)
|
|
33
|
+
val = val.to_sym if !!val
|
|
34
|
+
val
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def attributes=(attrs, guard_protected_attributes=true)
|
|
38
|
+
return if attrs.nil?
|
|
39
|
+
#check the attributes then turn them over
|
|
40
|
+
attrs.each do |k, v|
|
|
41
|
+
if self.class.has_enumerated_attribute?(k)
|
|
42
|
+
unless self.class.enumerated_attribute_allows_value?(k, v)
|
|
43
|
+
raise InvalidEnumeration, ":#{v.to_s} is not a defined enumeration value for the '#{k.to_s}' attribute", caller
|
|
44
|
+
end
|
|
45
|
+
attrs[k] = v.to_s
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
super
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def attributes
|
|
53
|
+
atts = super
|
|
54
|
+
atts.each do |k,v|
|
|
55
|
+
if self.class.has_enumerated_attribute?(k)
|
|
56
|
+
atts[k] = v.to_sym if v
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
atts
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def [](attr_name); read_enumerated_attribute(attr_name); end
|
|
63
|
+
def []=(attr_name, value); write_enumerated_attribute(attr_name, value); end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def attribute=(attr_name, value); write_enumerated_attribute(attr_name, value); end
|
|
68
|
+
|
|
69
|
+
module ClassMethods
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def construct_attributes_from_arguments(attribute_names, arguments)
|
|
73
|
+
attributes = super
|
|
74
|
+
attributes.each { |k,v| attributes[k] = v.to_s if has_enumerated_attribute?(k) }
|
|
75
|
+
attributes
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def instantiate(record)
|
|
79
|
+
object = super(record)
|
|
80
|
+
self.enumerated_attributes.each do |k,v|
|
|
81
|
+
unless object.has_attribute?(k) #only initialize the non-column enumerated attributes
|
|
82
|
+
object.write_enumerated_attribute(k, v.init_value)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
object
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def define_enumerated_attribute_new_method
|
|
89
|
+
class_eval do
|
|
90
|
+
class << self
|
|
91
|
+
unless method_defined?(:new_without_enumerated_attribute)
|
|
92
|
+
alias_method :new_without_enumerated_attribute, :new
|
|
93
|
+
def new(*args, &block)
|
|
94
|
+
result = new_without_enumerated_attribute(*args, &block)
|
|
95
|
+
params = (!args.empty? && args.first.instance_of?(Hash)) ? args.first : {}
|
|
96
|
+
params.each { |k, v| result.write_enumerated_attribute(k, v) }
|
|
97
|
+
result.initialize_enumerated_attributes(true)
|
|
98
|
+
yield result if block_given?
|
|
99
|
+
result
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module EnumeratedAttribute
|
|
2
|
+
module Integrations
|
|
3
|
+
|
|
4
|
+
module Default
|
|
5
|
+
def self.included(klass); klass.extend(ClassMethods); end
|
|
6
|
+
|
|
7
|
+
module ClassMethods
|
|
8
|
+
def define_enumerated_attribute_writer_method(name)
|
|
9
|
+
method_name = "#{name}=".to_sym
|
|
10
|
+
class_eval do
|
|
11
|
+
define_method(method_name) {|val| write_enumerated_attribute(name.to_sym, val) }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def define_enumerated_attribute_reader_method(name)
|
|
16
|
+
name = name.to_sym
|
|
17
|
+
class_eval do
|
|
18
|
+
define_method(name) { read_enumerated_attribute(name) }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module EnumeratedAttribute
|
|
2
|
+
module Integrations
|
|
3
|
+
|
|
4
|
+
module Object
|
|
5
|
+
def self.included(klass)
|
|
6
|
+
klass.extend(ClassMethods)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def write_enumerated_attribute(name, val)
|
|
10
|
+
name = name.to_s
|
|
11
|
+
val = nil if val == ''
|
|
12
|
+
val = val.to_sym if val
|
|
13
|
+
unless self.class.enumerated_attribute_allows_value?(name, val)
|
|
14
|
+
raise(InvalidEnumeration, "nil is not allowed on '#{name}' attribute, set :nil=>true option", caller) unless val
|
|
15
|
+
raise(InvalidEnumeration, ":#{val} is not a defined enumeration value for the '#{name}' attribute", caller)
|
|
16
|
+
end
|
|
17
|
+
instance_variable_set('@'+name, val)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def read_enumerated_attribute(name)
|
|
21
|
+
instance_variable_get('@'+name.to_s)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module ClassMethods
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def define_enumerated_attribute_new_method
|
|
28
|
+
class_eval do
|
|
29
|
+
class << self
|
|
30
|
+
unless method_defined?(:new_without_enumerated_attribute)
|
|
31
|
+
alias_method :new_without_enumerated_attribute, :new
|
|
32
|
+
def new(*args, &block)
|
|
33
|
+
result = new_without_enumerated_attribute(*args)
|
|
34
|
+
result.initialize_enumerated_attributes
|
|
35
|
+
yield result if block_given?
|
|
36
|
+
result
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
module EnumeratedAttribute
|
|
2
|
+
|
|
3
|
+
class MethodDefinition
|
|
4
|
+
attr_accessor :method_name, :negated, :argument
|
|
5
|
+
|
|
6
|
+
def initialize(name, arg, negated=false)
|
|
7
|
+
@method_name, @negated, @argument = name, negated, arg
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def is_predicate_method?; @method_name[-1, 1] == '?'; end
|
|
11
|
+
def has_method_name?; !!@method_name; end
|
|
12
|
+
def has_argument?; !!@argument; end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class MethodDefinitionDSL
|
|
16
|
+
attr_reader :initial_value, :pluralized_name, :decrementor_name, :incrementor_name
|
|
17
|
+
|
|
18
|
+
def initialize(class_obj, descriptor)
|
|
19
|
+
@class_obj = class_obj
|
|
20
|
+
@attr_name = descriptor.name
|
|
21
|
+
@attr_descriptor = descriptor #this is the enums array
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#we'll by pass this - they can use it if it helps make code more readable - not enforced - should it be??
|
|
25
|
+
def define
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def is_not(*args)
|
|
29
|
+
arg = args.first if args.length > 0
|
|
30
|
+
MethodDefinition.new(nil, arg, true)
|
|
31
|
+
end
|
|
32
|
+
alias :isnt :is_not
|
|
33
|
+
|
|
34
|
+
def is(*args)
|
|
35
|
+
arg = args.first if args.length > 0
|
|
36
|
+
MethodDefinition.new(nil, arg)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def method_missing(methId, *args, &block)
|
|
40
|
+
meth_name = methId.id2name
|
|
41
|
+
|
|
42
|
+
meth_def = nil
|
|
43
|
+
if args.size > 0
|
|
44
|
+
arg = args.first
|
|
45
|
+
if arg.instance_of?(EnumeratedAttribute::MethodDefinition)
|
|
46
|
+
if arg.has_method_name?
|
|
47
|
+
raise_method_syntax_error(meth_name, arg.method_name)
|
|
48
|
+
end
|
|
49
|
+
meth_def = arg
|
|
50
|
+
meth_def.method_name = meth_name
|
|
51
|
+
else
|
|
52
|
+
meth_def = MethodDefinition.new(meth_name, arg)
|
|
53
|
+
end
|
|
54
|
+
elsif block_given?
|
|
55
|
+
meth_def = MethodDefinition.new(meth_name, block)
|
|
56
|
+
else
|
|
57
|
+
raise_method_syntax_error(meth_name)
|
|
58
|
+
end
|
|
59
|
+
evaluate_method_definition(meth_def)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def init(value)
|
|
63
|
+
if (!@attr_descriptor.empty? && !@attr_descriptor.include?(value.to_sym))
|
|
64
|
+
raise(InvalidDefinition, "'#{value}' in method 'init' is not an enumeration value for :#{@attr_name} attribute", caller)
|
|
65
|
+
end
|
|
66
|
+
@initial_value = value
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def decrementor(value); @decrementor_name = value; end
|
|
70
|
+
def incrementor(value); @incrementor_name = value; end
|
|
71
|
+
def enums_accessor(value); @pluralized_name = value; end
|
|
72
|
+
alias_method :inc, :incrementor
|
|
73
|
+
alias_method :dec, :decrementor
|
|
74
|
+
alias_method :enums, :enums_accessor
|
|
75
|
+
alias_method :plural, :enums_accessor
|
|
76
|
+
|
|
77
|
+
def label(hash)
|
|
78
|
+
raise(InvalidDefinition, "label or labels keyword should be followed by a hash of :enum_value=>'label'", caller) unless hash.is_a?(Hash)
|
|
79
|
+
hash.each do |k,v|
|
|
80
|
+
raise(InvalidDefinition, "#{k} is not an enumeration value for :#{@attr_name} attribute", caller) unless (k.is_a?(Symbol) && @attr_descriptor.include?(k))
|
|
81
|
+
raise(InvalidDefinition, "#{v} is not a string. Labels should be strings", caller) unless v.is_a?(String)
|
|
82
|
+
@attr_descriptor.set_label(k, v)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
alias_method :labels, :label
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
def raise_method_syntax_error(meth_name, offending_token=nil)
|
|
90
|
+
suffix = offending_token ? "found '#{offending_token}'" : "found nothing"
|
|
91
|
+
followed_by = (meth_name[-1,1] == '?' ? "is_not, an enumeration value, an array of enumeration values, " : "") + "a proc, lambda or code block"
|
|
92
|
+
raise InvalidDefinition, "'#{meth_name}' should be followed by #{followed_by} -- but #{suffix}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def evaluate_method_definition(mdef)
|
|
96
|
+
unless mdef.has_argument?
|
|
97
|
+
return raise_method_syntax_error(mdef.method_name)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
if mdef.is_predicate_method?
|
|
101
|
+
case mdef.argument
|
|
102
|
+
when String
|
|
103
|
+
return create_custom_method_for_symbol_or_string(mdef)
|
|
104
|
+
when Symbol
|
|
105
|
+
return create_custom_method_for_symbol_or_string(mdef)
|
|
106
|
+
when Array
|
|
107
|
+
return create_custom_method_for_array_of_enums(mdef)
|
|
108
|
+
when Proc
|
|
109
|
+
return create_custom_method_for_proc(mdef)
|
|
110
|
+
end
|
|
111
|
+
else #action method
|
|
112
|
+
if mdef.argument.instance_of?(Proc)
|
|
113
|
+
return create_custom_method_for_proc(mdef)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
raise_method_syntax_error(mdef.method_name, mdef.argument)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def create_custom_method_for_proc(mdef)
|
|
120
|
+
@class_obj.send(:define_method, mdef.method_name, mdef.argument)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def create_custom_method_for_symbol_or_string(mdef)
|
|
124
|
+
if (!@attr_descriptor.empty? && !@attr_descriptor.include?(mdef.argument.to_sym))
|
|
125
|
+
raise(InvalidDefinition, "'#{mdef.argument}' in method '#{mdef.method_name}' is not an enumeration value for :#{@attr_name} attribute", caller)
|
|
126
|
+
end
|
|
127
|
+
@class_obj.class_eval("def #{mdef.method_name}; @#{@attr_name} #{mdef.negated ? '!=' : '=='} :#{mdef.argument}; end")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def create_custom_method_for_array_of_enums(mdef)
|
|
131
|
+
if !@attr_descriptor.empty?
|
|
132
|
+
mdef.argument.each do |m|
|
|
133
|
+
if !@attr_descriptor.include?(m.to_sym)
|
|
134
|
+
raise(InvalidDefinition, "'#{m}' in method '#{mdef.method_name}' is not an enumeration value for :#{@attr_name} attribute", caller)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
@class_obj.class_eval("def #{mdef.method_name}; #{mdef.negated ? '!' : ''}[:#{mdef.argument.join(',:')}].include?(@#{@attr_name}); end")
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'active_record/connection_adapters/abstract/schema_definitions'
|
|
2
|
+
|
|
3
|
+
if defined?(ActiveRecord)
|
|
4
|
+
module ActiveRecord
|
|
5
|
+
module ConnectionAdapters
|
|
6
|
+
class TableDefinition
|
|
7
|
+
def column_with_enumerated_attribute(name, type, options = {})
|
|
8
|
+
type = 'string' if type.to_s == 'enum'
|
|
9
|
+
column_without_enumerated_attribute(name, type, options)
|
|
10
|
+
end
|
|
11
|
+
safe_alias_method_chain :column, :enumerated_attribute
|
|
12
|
+
|
|
13
|
+
def enum(*args)
|
|
14
|
+
options = args.extract_options!
|
|
15
|
+
column_names = args
|
|
16
|
+
column_names.each { |name| column(name, 'string', options) }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#ARGV is used by generators -- if it contains one of these generator commands - add enumeration support
|
|
24
|
+
#unless ((ARGV || []) & ["scaffold", "rspec_scaffold", "nifty_scaffold"]).empty?
|
|
25
|
+
if ((ARGV || []).any?{|o| o =~ /scaffold/ })
|
|
26
|
+
require 'rails_generator' rescue nil
|
|
27
|
+
begin
|
|
28
|
+
require 'rails/generators'
|
|
29
|
+
require 'rails/generators/generated_attribute'
|
|
30
|
+
rescue
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
module Rails
|
|
34
|
+
module Generator
|
|
35
|
+
class GeneratedAttribute
|
|
36
|
+
def field_type_with_enumerated_attribute
|
|
37
|
+
return (@field_type = :enum_select) if type == :enum
|
|
38
|
+
field_type_without_enumerated_attribute
|
|
39
|
+
end
|
|
40
|
+
alias_method_chain :field_type, :enumerated_attribute
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if defined?(ActionView::Base)
|
|
47
|
+
module ActionView
|
|
48
|
+
module Helpers
|
|
49
|
+
|
|
50
|
+
#form_options_helper.rb
|
|
51
|
+
module FormOptionsHelper
|
|
52
|
+
#def select
|
|
53
|
+
def enum_select(object, method, options={}, html_options={})
|
|
54
|
+
InstanceTag.new(object, method, self, options.delete(:object)).to_enum_select_tag(options, html_options)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class InstanceTag
|
|
59
|
+
def to_enum_select_tag(options, html_options={})
|
|
60
|
+
choices = []
|
|
61
|
+
if self.object.respond_to?(:enums)
|
|
62
|
+
enums = self.object.enums(method_name.to_sym)
|
|
63
|
+
choices = enums ? enums.select_options : []
|
|
64
|
+
if (value = self.object.__send__(method_name.to_sym))
|
|
65
|
+
options[:selected] ||= value.to_s
|
|
66
|
+
else
|
|
67
|
+
options[:include_blank] = enums.allows_nil? if options[:include_blank].nil?
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
to_select_tag(choices, options, html_options)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#initialize record_name, method, self
|
|
74
|
+
def to_tag_with_enumerated_attribute(options={})
|
|
75
|
+
#look for an enum
|
|
76
|
+
if (column_type == :string &&
|
|
77
|
+
self.object.class.respond_to?(:has_enumerated_attribute?) &&
|
|
78
|
+
self.object.class.has_enumerated_attribute?(method_name.to_sym))
|
|
79
|
+
to_enum_select_tag(options)
|
|
80
|
+
else
|
|
81
|
+
to_tag_without_enumerated_attribute(options)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
alias_method_chain :to_tag, :enumerated_attribute
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
class FormBuilder
|
|
88
|
+
def enum_select(method, options={}, html_options={})
|
|
89
|
+
@template.enum_select(@object_name, method, objectify_options(options), @default_options.merge(html_options))
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
|