pluginaweek-enumerate_by 0.4.2

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/CHANGELOG.rdoc ADDED
@@ -0,0 +1,111 @@
1
+ == master
2
+
3
+ * Improve compatibility with the stable branch of Rails 2.3 [Michael Schuerig]
4
+
5
+ == 0.4.2 / 2009-05-03
6
+
7
+ * Fix bootstrapping without ids not working on update for certain database adapters
8
+
9
+ == 0.4.1 / 2009-05-01
10
+
11
+ * Improve #fast_bootstrap speed by 50% by using the connection directly
12
+
13
+ == 0.4.0 / 2009-04-30
14
+
15
+ * Allow cache to be cleared on a per-enumeration basis
16
+ * Add #fast_bootstrap for bootstrapping large numbers of records
17
+ * Don't require an id during bootstrap
18
+ * Allow bootstrapping to be easily added to non-enumerations
19
+ * Cache results for #exists? / #calculate
20
+ * Add the ability to skip the internal cache via Model#uncached
21
+ * Add Model#find_all_by_enumerator
22
+ * Don't internally rely on Model#[] being available since it may conflict with other plugins
23
+ * Enable caching by default for all enumerations
24
+ * Allow caching to be turned off on an application-wide basis
25
+ * Allow cache store to be configurable
26
+ * Automatically trigger in-memory caching of the enumeration's table when bootstrapping
27
+ * Add #bootstrap for automatically synchronizing the records in an enumeration's table
28
+ * Improve serialization performance
29
+ * No longer use tableless models
30
+ * Re-brand under the enumerate_by name
31
+
32
+ == 0.3.0 / 2008-12-14
33
+
34
+ * Remove the PluginAWeek namespace
35
+
36
+ == 0.2.6 / 2008-11-29
37
+
38
+ * Fix enumeration collections not being able to convert to JSON
39
+ * Add support for multiple enumeration values in finder conditions, e.g. Car.find_all_by_color(%w(red blue))
40
+
41
+ == 0.2.5 / 2008-10-26
42
+
43
+ * Fix non-ActiveRecord associations (e.g. ActiveResource) failing
44
+ * Fix reloading of associations not working
45
+ * Raise an exception if equality is performed with an invalid enumeration identifier
46
+ * Change how the base module is included to prevent namespacing conflicts
47
+
48
+ == 0.2.4 / 2008-08-31
49
+
50
+ * Add support for serialization in JSON/XML
51
+
52
+ == 0.2.3 / 2008-06-29
53
+
54
+ * Fix named scope for enumerations that belong_to other enumerations
55
+
56
+ == 0.2.2 / 2008-06-23
57
+
58
+ * Remove log files from gems
59
+
60
+ == 0.2.1 / 2008-06-22
61
+
62
+ * Improve documentation
63
+
64
+ == 0.2.0 / 2008-06-22
65
+
66
+ * Improve performance by disabling unnecessary ActiveRecord hooks including callbacks, dirty attributes, timestamps, and transactions (important for enumerations with large sets of values)
67
+ * Don't let #create silently fail
68
+ * Remove ability to reset the cache
69
+ * Improve performance by adding pre-indexing of enumeration attributes (important for enumerations with large sets of values)
70
+ * Remove support for array comparison
71
+ * Remove support for multiple enumeration attributes
72
+
73
+ == 0.1.2 / 2008-06-15
74
+
75
+ * Avoid string evaluation for dynamic methods
76
+ * Fix has_many/has_one associations improperly loading classes too early
77
+ * Add support for string and array comparison
78
+ * Use after_create/after_destroy callbacks instead of defining the callback method itself
79
+
80
+ == 0.1.1 / 2008-05-14
81
+
82
+ * Fix automatically clearing association cache when it shouldn't be
83
+
84
+ == 0.1.0 / 2008-05-05
85
+
86
+ * Add support for overriding the unique attribute that defines an enumeration e.g.
87
+
88
+ acts_as_enumeration :title
89
+ acts_as_enumeration :controller, :action
90
+
91
+ * Add support for using enumerations in has_many/has_one associations
92
+ * Add support for Rails 2.0
93
+ * Use has_finder to auto-generate finders for each enumeration value after defining a belongs_to association
94
+ * Removed support for database-backed enumerations in favor of always using virtual enumerations
95
+ * Fix enumerations failing when being reloaded
96
+ * Fix problems with setting enumeration attributes to nil
97
+ * Add inheritance support for virtual enumerations
98
+ * Add support for converting unsafe identifier names (like "red!") to their safe symbol equivalent ("red")
99
+ * Add ability to use truth accessors for determing the identifier name
100
+ * Add support for virtual enumerations that don't need to be backed by the database
101
+
102
+ == 0.0.2 / 2007-09-26
103
+
104
+ * Move test fixtures out of the test application root directory
105
+ * Convert dos newlines to unix newlines
106
+
107
+ == 0.0.1 / 2007-08-04
108
+
109
+ * Initial public release
110
+ * Add/refactor unit tests
111
+ * Add documentation
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006-2009 Aaron Pfeifer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,117 @@
1
+ = enumerate_by
2
+
3
+ +enumerate_by+ adds support for declaring an ActiveRecord class as an
4
+ enumeration.
5
+
6
+ == Resources
7
+
8
+ API
9
+
10
+ * http://api.pluginaweek.org/enumerate_by
11
+
12
+ Bugs
13
+
14
+ * http://pluginaweek.lighthouseapp.com/projects/13265-enumerate_by
15
+
16
+ Development
17
+
18
+ * http://github.com/pluginaweek/enumerate_by
19
+
20
+ Source
21
+
22
+ * git://github.com/pluginaweek/enumerate_by.git
23
+
24
+ == Description
25
+
26
+ Support for enumerations is dependent on the type of database you use. For
27
+ example, MySQL has native support for the enum data type. However, there is
28
+ no native Rails support for defining enumerations and the associations between
29
+ it and other models in the application.
30
+
31
+ In addition, enumerations may often have more complex data and/or functionality
32
+ associated with it that cannot simply be describe in a single column.
33
+
34
+ enumerate_by adds support for pseudo-enumerations in Rails by allowing the
35
+ enumeration's records to be defined in code, but continuing to express the
36
+ relationship between an enumeration and other models using ActiveRecord
37
+ associations. The important thing to remember, however, is that while the
38
+ associations exist, the enumerator is always used outside of the application,
39
+ while either the enumerator or the enumerator's record would be referenced
40
+ *within* the application. This means that you would reference a Color record
41
+ via it's enumerator (such as "red") everywhere in the code (conditions,
42
+ assigning associations, forms, etc.), but it would always be stored in the
43
+ database as a true association with the integer value of 1.
44
+
45
+ == Usage
46
+
47
+ class Color < ActiveRecord::Base
48
+ enumerate_by :name
49
+
50
+ belongs_to :group, :class_name => 'ColorGroup'
51
+ has_many :cars
52
+
53
+ bootstrap(
54
+ {:id => 1, :name => 'red', :group => 'RGB'},
55
+ {:id => 2, :name => 'blue', :group => 'RGB'},
56
+ {:id => 3, :name => 'green', :group => 'RGB'},
57
+ {:id => 4, :name => 'cyan', :group => 'CMYK'}
58
+ )
59
+ end
60
+
61
+ class ColorGroup < ActiveRecord::Base
62
+ enumerate_by :name
63
+
64
+ has_many :colors, :foreign_key => 'group_id'
65
+
66
+ bootstrap(
67
+ {:id => 1, :name => 'RGB'},
68
+ {:id => 2, :name => 'CMYK'}
69
+ )
70
+ end
71
+
72
+ class Car < ActiveRecord::Base
73
+ belongs_to :color
74
+ end
75
+
76
+ Each of the above models is backed by the database with its own table. Both
77
+ the Color and ColorGroup enumerations automatically synchronize with the
78
+ records in the database based on what's define in their bootstrap data.
79
+
80
+ The enumerations and their associations can be then be used like so:
81
+
82
+ car = Car.create(:color => 'red') # => #<Car id: 1, color_id: 1>
83
+ car.color # => #<Color id: 1, name: "red">
84
+ car.color == 'red' # => true
85
+ car.color.name # => "red"
86
+
87
+ car.color = 'blue'
88
+ car.save # => true
89
+ car # => #<Car id: 1, color_id: 2>
90
+
91
+ # Serialization
92
+ car.to_json # => "{id: 1, color: \"blue\"}"
93
+ car.to_xml # => "<car><id type=\"integer\">1</id><color>blue</color></car>"
94
+
95
+ # Lookup
96
+ Car.with_color('blue') # => [#<Car id: 1, color_id: 2>]
97
+ car = Car.find_by_color('blue') # => #<Car id: 1, color_id: 2>
98
+ car.color == Color['blue'] # => true
99
+
100
+ As mentioned previously, the important thing to note from the above example is
101
+ that from an external perspective, "color" is simply an attribute on the Car.
102
+ However, it's backed by a more complex association and model that allows Color
103
+ to include advanced functionality that would normally not be possible with a
104
+ simple attribute.
105
+
106
+ == Testing
107
+
108
+ Before you can run any tests, the following gem must be installed:
109
+ * plugin_test_helper[http://github.com/pluginaweek/plugin_test_helper]
110
+
111
+ To run against a specific version of Rails:
112
+
113
+ rake test RAILS_FRAMEWORK_ROOT=/path/to/rails
114
+
115
+ == Dependencies
116
+
117
+ * Rails 2.1 or later
data/Rakefile ADDED
@@ -0,0 +1,96 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+ require 'rake/contrib/sshpublisher'
5
+
6
+ spec = Gem::Specification.new do |s|
7
+ s.name = 'enumerate_by'
8
+ s.version = '0.4.2'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.summary = 'Adds support for declaring an ActiveRecord class as an enumeration'
11
+ s.description = s.summary
12
+
13
+ s.files = FileList['{lib,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/app_root/{log,log/*,script,script/*}']
14
+ s.require_path = 'lib'
15
+ s.has_rdoc = true
16
+ s.test_files = Dir['test/**/*_test.rb']
17
+
18
+ s.author = 'Aaron Pfeifer'
19
+ s.email = 'aaron@pluginaweek.org'
20
+ s.homepage = 'http://www.pluginaweek.org'
21
+ s.rubyforge_project = 'pluginaweek'
22
+ end
23
+
24
+ desc 'Default: run all tests.'
25
+ task :default => :test
26
+
27
+ desc "Test the #{spec.name} plugin."
28
+ Rake::TestTask.new(:test) do |t|
29
+ t.libs << 'lib'
30
+ t.test_files = spec.test_files
31
+ t.verbose = true
32
+ end
33
+
34
+ begin
35
+ require 'rcov/rcovtask'
36
+ namespace :test do
37
+ desc "Test the #{spec.name} plugin with Rcov."
38
+ Rcov::RcovTask.new(:rcov) do |t|
39
+ t.libs << 'lib'
40
+ t.test_files = spec.test_files
41
+ t.rcov_opts << '--exclude="^(?!lib/)"'
42
+ t.verbose = true
43
+ end
44
+ end
45
+ rescue LoadError
46
+ end
47
+
48
+ desc "Generate documentation for the #{spec.name} plugin."
49
+ Rake::RDocTask.new(:rdoc) do |rdoc|
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = spec.name
52
+ rdoc.template = '../rdoc_template.rb'
53
+ rdoc.options << '--line-numbers' << '--inline-source'
54
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
55
+ end
56
+
57
+ desc 'Generate a gemspec file.'
58
+ task :gemspec do
59
+ File.open("#{spec.name}.gemspec", 'w') do |f|
60
+ f.write spec.to_ruby
61
+ end
62
+ end
63
+
64
+ Rake::GemPackageTask.new(spec) do |p|
65
+ p.gem_spec = spec
66
+ p.need_tar = true
67
+ p.need_zip = true
68
+ end
69
+
70
+ desc 'Publish the beta gem.'
71
+ task :pgem => [:package] do
72
+ Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{spec.name}-#{spec.version}.gem").upload
73
+ end
74
+
75
+ desc 'Publish the API documentation.'
76
+ task :pdoc => [:rdoc] do
77
+ Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{spec.name}", 'rdoc').upload
78
+ end
79
+
80
+ desc 'Publish the API docs and gem'
81
+ task :publish => [:pgem, :pdoc, :release]
82
+
83
+ desc 'Publish the release files to RubyForge.'
84
+ task :release => [:gem, :package] do
85
+ require 'rubyforge'
86
+
87
+ ruby_forge = RubyForge.new.configure
88
+ ruby_forge.login
89
+
90
+ %w(gem tgz zip).each do |ext|
91
+ file = "pkg/#{spec.name}-#{spec.version}.#{ext}"
92
+ puts "Releasing #{File.basename(file)}..."
93
+
94
+ ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file)
95
+ end
96
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'enumerate_by'
@@ -0,0 +1,109 @@
1
+ module EnumerateBy
2
+ module Extensions #:nodoc:
3
+ # Adds a set of helpers for using enumerations in associations, including
4
+ # named scopes and assignment via enumerators.
5
+ #
6
+ # The examples below assume the following models have been defined:
7
+ #
8
+ # class Color < ActiveRecord::Base
9
+ # enumerate_by :name
10
+ #
11
+ # bootstrap(
12
+ # {:id => 1, :name => 'red'},
13
+ # {:id => 2, :name => 'blue'},
14
+ # {:id => 3, :name => 'green'}
15
+ # )
16
+ # end
17
+ #
18
+ # class Car < ActiveRecord::Base
19
+ # belongs_to :color
20
+ # end
21
+ #
22
+ # == Named scopes
23
+ #
24
+ # A pair of named scopes are generated for each +belongs_to+ association
25
+ # that is identified by an enumeration. In this case, the following
26
+ # named scopes get generated:
27
+ # * +with_color+ / +with_colors+ - Finds all cars with the given color(s)
28
+ # * +without_color+ / +without_colors+ - Finds all cars without the given color(s)
29
+ #
30
+ # For example,
31
+ #
32
+ # Car.with_color('red') # Cars with the color name "red"
33
+ # Car.without_color('red') # Cars without the color name "red"
34
+ # Car.with_colors('red', 'blue') # Cars with either the color names "red" or "blue"
35
+ #
36
+ # == Association assignment
37
+ #
38
+ # Normally, +belongs_to+ associations are assigned with either the actual
39
+ # record or through its primary key. When used with enumerations, support
40
+ # is added for assigning these associations through the enumerators
41
+ # defined for the class.
42
+ #
43
+ # For example,
44
+ #
45
+ # # With valid enumerator
46
+ # car = Car.new # => #<Car id: nil, color_id: nil>
47
+ # car.color = 'red'
48
+ # car.color_id # => 1
49
+ # car.color # => #<Color id: 1, name: "red">
50
+ #
51
+ # # With invalid enumerator
52
+ # car = Car.new # => #<Car id: nil, color_id: nil>
53
+ # car.color = 'invalid'
54
+ # car.color_id # => nil
55
+ # car.color # => nil
56
+ #
57
+ # In the above example, the actual Color association is automatically
58
+ # looked up by finding the Color record identified by the enumerator the
59
+ # given enumerator ("red" in this case).
60
+ module Associations
61
+ def self.extended(base) #:nodoc:
62
+ class << base
63
+ alias_method_chain :belongs_to, :enumerations
64
+ end
65
+ end
66
+
67
+ # Adds support for belongs_to and enumerations
68
+ def belongs_to_with_enumerations(association_id, options = {})
69
+ belongs_to_without_enumerations(association_id, options)
70
+
71
+ # Override accessor if class is valid enumeration
72
+ reflection = reflections[association_id.to_sym]
73
+ if !reflection.options[:polymorphic] && (reflection.klass < ActiveRecord::Base) && reflection.klass.enumeration?
74
+ name = reflection.name
75
+ primary_key_name = reflection.primary_key_name
76
+ class_name = reflection.class_name
77
+ klass = reflection.klass
78
+
79
+ # Inclusion scopes
80
+ %W(with_#{name} with_#{name.to_s.pluralize}).each do |scope_name|
81
+ named_scope scope_name.to_sym, lambda {|*enumerators| {
82
+ :conditions => {primary_key_name => klass.find_all_by_enumerator!(enumerators).map(&:id)}
83
+ }}
84
+ end
85
+
86
+ # Exclusion scopes
87
+ %W(without_#{name} without_#{name.to_s.pluralize}).each do |scope_name|
88
+ named_scope scope_name.to_sym, lambda {|*enumerators| {
89
+ :conditions => ["#{primary_key_name} NOT IN (?)", klass.find_all_by_enumerator!(enumerators).map(&:id)]
90
+ }}
91
+ end
92
+
93
+ # Hook in shortcut writer
94
+ define_method("#{name}_with_enumerators=") do |new_value|
95
+ send("#{name}_without_enumerators=", new_value.is_a?(klass) ? new_value : klass.find_by_enumerator(new_value))
96
+ end
97
+ alias_method_chain "#{name}=", :enumerators
98
+
99
+ # Track the association
100
+ enumeration_associations[primary_key_name.to_s] = name.to_s
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ ActiveRecord::Base.class_eval do
108
+ extend EnumerateBy::Extensions::Associations
109
+ end
@@ -0,0 +1,130 @@
1
+ module EnumerateBy
2
+ module Extensions #:nodoc:
3
+ # Adds support for using enumerators in dynamic finders and conditions.
4
+ # For example suppose the following models are defined:
5
+ #
6
+ # class Color < ActiveRecord::Base
7
+ # enumerate_by :name
8
+ #
9
+ # bootstrap(
10
+ # {:id => 1, :name => 'red'},
11
+ # {:id => 2, :name => 'blue'},
12
+ # {:id => 3, :name => 'green'}
13
+ # )
14
+ # end
15
+ #
16
+ # class Car < ActiveRecord::Base
17
+ # belongs_to :color
18
+ # end
19
+ #
20
+ # Normally, looking up all cars associated with a particular color
21
+ # requires either a join or knowing the id of the color upfront:
22
+ #
23
+ # Car.find(:all, :joins => :color, :conditions => {:colors => {:name => 'red}})
24
+ # Car.find_by_color_id(1)
25
+ #
26
+ # Instead of doing this manually, the color can be referenced directly
27
+ # via its enumerator like so:
28
+ #
29
+ # # With dynamic finders
30
+ # Car.find_by_color('red')
31
+ #
32
+ # # With conditions
33
+ # Car.all(:conditions => {:color => 'red'})
34
+ #
35
+ # # With updates
36
+ # Car.update_all(:color => 'red')
37
+ #
38
+ # In the above examples, +color+ is essentially treated like a normal
39
+ # attribute on the class, instead triggering the associated Color record
40
+ # to be looked up and replacing the condition with a +color_id+ condition.
41
+ #
42
+ # *Note* that this does not add an additional join on the +colors+ table
43
+ # since the lookup of the color's id should be relatively fast when it's
44
+ # cached in-memory.
45
+ module BaseConditions
46
+ def self.extended(base) #:nodoc:
47
+ class << base
48
+ alias_method_chain :construct_attributes_from_arguments, :enumerations
49
+ alias_method_chain :sanitize_sql_hash_for_conditions, :enumerations
50
+ alias_method_chain :sanitize_sql_hash_for_assignment, :enumerations
51
+ alias_method_chain :all_attributes_exists?, :enumerations
52
+ end
53
+ end
54
+
55
+ # Add support for dynamic finders
56
+ def construct_attributes_from_arguments_with_enumerations(attribute_names, arguments)
57
+ attributes = construct_attributes_from_arguments_without_enumerations(attribute_names, arguments)
58
+ attribute_names.each_with_index do |name, idx|
59
+ if options = enumerator_options_for(name, arguments[idx])
60
+ attributes.delete(name)
61
+ attributes.merge!(options)
62
+ end
63
+ end
64
+
65
+ attributes
66
+ end
67
+
68
+ # Sanitizes a hash of attribute/value pairs into SQL conditions for a WHERE clause.
69
+ def sanitize_sql_hash_for_conditions_with_enumerations(attrs, *args)
70
+ replace_enumerations_in_hash(attrs)
71
+ sanitize_sql_hash_for_conditions_without_enumerations(attrs, *args)
72
+ end
73
+
74
+ # Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.
75
+ def sanitize_sql_hash_for_assignment_with_enumerations(attrs, *args)
76
+ replace_enumerations_in_hash(attrs, false)
77
+ sanitize_sql_hash_for_assignment_without_enumerations(attrs, *args)
78
+ end
79
+
80
+ # Make sure dynamic finders don't fail since it won't find the association
81
+ # name in its columns
82
+ def all_attributes_exists_with_enumerations?(attribute_names)
83
+ exists = all_attributes_exists_without_enumerations?(attribute_names)
84
+ exists ||= attribute_names.all? do |name|
85
+ column_methods_hash.include?(name.to_sym) || reflect_on_enumeration(name)
86
+ end
87
+ end
88
+
89
+ private
90
+ # Finds all of the attributes that are enumerations and replaces them
91
+ # with the correct enumerator id
92
+ def replace_enumerations_in_hash(attrs, allow_multiple = true) #:nodoc:
93
+ attrs.each do |attr, value|
94
+ if options = enumerator_options_for(attr, value, allow_multiple)
95
+ attrs.delete(attr)
96
+ attrs.merge!(options)
97
+ end
98
+ end
99
+ end
100
+
101
+ # Generates the enumerator lookup options for the given association
102
+ # name and enumerator value. If the association is *not* for an
103
+ # enumeration, then this will return nil.
104
+ def enumerator_options_for(name, enumerator, allow_multiple = true)
105
+ if reflection = reflect_on_enumeration(name)
106
+ klass = reflection.klass
107
+ attribute = reflection.primary_key_name
108
+ id = if allow_multiple && enumerator.is_a?(Array)
109
+ enumerator.map {|enumerator| klass.find_by_enumerator!(enumerator).id}
110
+ else
111
+ klass.find_by_enumerator!(enumerator).id
112
+ end
113
+
114
+ {attribute => id}
115
+ end
116
+ end
117
+
118
+ # Attempts to find an association with the given name *and* represents
119
+ # an enumeration
120
+ def reflect_on_enumeration(name)
121
+ reflection = reflect_on_association(name.to_sym)
122
+ reflection if reflection && reflection.klass.enumeration?
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ ActiveRecord::Base.class_eval do
129
+ extend EnumerateBy::Extensions::BaseConditions
130
+ end