active_enum 0.8.2 → 0.9.0
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 +5 -0
- data/README.rdoc +4 -3
- data/active_enum.gemspec +3 -3
- data/lib/active_enum.rb +19 -5
- data/lib/active_enum/extensions.rb +4 -6
- data/lib/active_enum/storage/active_record_store.rb +64 -0
- data/lib/active_enum/version.rb +1 -1
- data/lib/generators/active_enum/install_generator.rb +14 -0
- data/lib/generators/active_enum/templates/active_enum.rb +24 -0
- data/spec/active_enum/storage/active_record_store_spec.rb +133 -0
- data/spec/active_enum_spec.rb +34 -9
- data/spec/schema.rb +11 -0
- data/spec/spec_helper.rb +2 -0
- metadata +8 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
[0.9.0] : 2010-08-11
|
2
|
+
- Full ActiveModel support for enumerate extension. Use ActiveEnum.extend_classes array to indicate classes to extend.
|
3
|
+
- Added generator for initializer config file with all settings.
|
4
|
+
- Added setup block for config
|
5
|
+
|
1
6
|
[0.8.2] : 2010-08-01
|
2
7
|
- Fix method name clash of enum_for which is defined on Object
|
3
8
|
- Refactor extension method definitions
|
data/README.rdoc
CHANGED
@@ -15,6 +15,10 @@ Put this in your Gemfile
|
|
15
15
|
|
16
16
|
gem 'active_enum'
|
17
17
|
|
18
|
+
Then generate the config initializer file
|
19
|
+
|
20
|
+
rails generate active_enum:install
|
21
|
+
|
18
22
|
|
19
23
|
== Example
|
20
24
|
|
@@ -192,10 +196,7 @@ The input type will be automatically detected for enumerated attributes. You can
|
|
192
196
|
|
193
197
|
|
194
198
|
== TODO
|
195
|
-
* more docs
|
196
199
|
* storage options of memory, database or yaml
|
197
200
|
* use custom method name for the enumerated attribute
|
198
|
-
* named_scopes
|
199
|
-
* question methods for enum names e.g. user.male?
|
200
201
|
|
201
202
|
Copyright (c) 2009 Adam Meehan, released under the MIT license
|
data/active_enum.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{active_enum}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.9.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Adam Meehan"]
|
9
9
|
s.autorequire = %q{active_enum}
|
10
|
-
s.date = %q{2010-08-
|
10
|
+
s.date = %q{2010-08-11}
|
11
11
|
s.description = %q{Define enum classes in Rails and use them to enumerate ActiveRecord attributes}
|
12
12
|
s.email = %q{adam.meehan@gmail.com}
|
13
13
|
s.extra_rdoc_files = ["README.rdoc"]
|
14
|
-
s.files = ["active_enum.gemspec", "MIT-LICENSE", "CHANGELOG", "README.rdoc", "Rakefile", "lib/active_enum", "lib/active_enum/acts_as_enum.rb", "lib/active_enum/base.rb", "lib/active_enum/extensions.rb", "lib/active_enum/form_helpers", "lib/active_enum/form_helpers/formtastic.rb", "lib/active_enum/form_helpers/simple_form.rb", "lib/active_enum/storage", "lib/active_enum/storage/abstract_store.rb", "lib/active_enum/storage/memory_store.rb", "lib/active_enum/version.rb", "lib/active_enum.rb", "lib/generators", "spec/active_enum", "spec/active_enum/acts_as_enum_spec.rb", "spec/active_enum/base_spec.rb", "spec/active_enum/extensions_spec.rb", "spec/active_enum/form_helpers", "spec/active_enum/form_helpers/formtastic_spec.rb", "spec/active_enum/form_helpers/simple_form_spec.rb", "spec/active_enum/storage", "spec/active_enum/storage/memory_store_spec.rb", "spec/active_enum_spec.rb", "spec/schema.rb", "spec/spec_helper.rb"]
|
14
|
+
s.files = ["active_enum.gemspec", "MIT-LICENSE", "CHANGELOG", "README.rdoc", "Rakefile", "lib/active_enum", "lib/active_enum/acts_as_enum.rb", "lib/active_enum/base.rb", "lib/active_enum/extensions.rb", "lib/active_enum/form_helpers", "lib/active_enum/form_helpers/formtastic.rb", "lib/active_enum/form_helpers/simple_form.rb", "lib/active_enum/storage", "lib/active_enum/storage/abstract_store.rb", "lib/active_enum/storage/active_record_store.rb", "lib/active_enum/storage/memory_store.rb", "lib/active_enum/version.rb", "lib/active_enum.rb", "lib/generators", "lib/generators/active_enum", "lib/generators/active_enum/install_generator.rb", "lib/generators/active_enum/templates", "lib/generators/active_enum/templates/active_enum.rb", "spec/active_enum", "spec/active_enum/acts_as_enum_spec.rb", "spec/active_enum/base_spec.rb", "spec/active_enum/extensions_spec.rb", "spec/active_enum/form_helpers", "spec/active_enum/form_helpers/formtastic_spec.rb", "spec/active_enum/form_helpers/simple_form_spec.rb", "spec/active_enum/storage", "spec/active_enum/storage/active_record_store_spec.rb", "spec/active_enum/storage/memory_store_spec.rb", "spec/active_enum_spec.rb", "spec/schema.rb", "spec/spec_helper.rb"]
|
15
15
|
s.homepage = %q{http://github.com/adzap/active_enum}
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
s.rubyforge_project = %q{active_enum}
|
data/lib/active_enum.rb
CHANGED
@@ -6,15 +6,28 @@ require 'active_enum/version'
|
|
6
6
|
|
7
7
|
module ActiveEnum
|
8
8
|
mattr_accessor :enum_classes
|
9
|
-
|
9
|
+
@@enum_classes = []
|
10
10
|
|
11
11
|
mattr_accessor :use_name_as_value
|
12
|
-
|
12
|
+
@@use_name_as_value = false
|
13
13
|
|
14
14
|
mattr_accessor :storage
|
15
|
-
|
15
|
+
@@storage = :memory
|
16
16
|
|
17
|
-
|
17
|
+
mattr_accessor :extend_classes
|
18
|
+
@@extend_classes = []
|
19
|
+
|
20
|
+
def self.extend_classes=(klasses)
|
21
|
+
@@extend_classes = klasses
|
22
|
+
klasses.each {|klass| klass.send(:include, ActiveEnum::Extensions) }
|
23
|
+
end
|
24
|
+
|
25
|
+
# Setup method for plugin configuration
|
26
|
+
def self.setup
|
27
|
+
yield self
|
28
|
+
end
|
29
|
+
|
30
|
+
class EnumDefinitions
|
18
31
|
def enum(name, &block)
|
19
32
|
class_name = name.to_s.camelize
|
20
33
|
eval("class #{class_name} < ActiveEnum::Base; end", TOPLEVEL_BINDING)
|
@@ -23,9 +36,10 @@ module ActiveEnum
|
|
23
36
|
end
|
24
37
|
end
|
25
38
|
|
39
|
+
# Define enums in bulk
|
26
40
|
def self.define(&block)
|
27
41
|
raise "Define requires block" unless block_given?
|
28
|
-
|
42
|
+
EnumDefinitions.new.instance_eval(&block)
|
29
43
|
end
|
30
44
|
|
31
45
|
end
|
@@ -2,11 +2,11 @@ module ActiveEnum
|
|
2
2
|
class EnumNotFound < StandardError; end
|
3
3
|
|
4
4
|
module Extensions
|
5
|
+
extend ActiveSupport::Concern
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
base.enumerated_attributes = {}
|
7
|
+
included do
|
8
|
+
class_inheritable_accessor :enumerated_attributes
|
9
|
+
self.enumerated_attributes = {}
|
10
10
|
end
|
11
11
|
|
12
12
|
module ClassMethods
|
@@ -122,5 +122,3 @@ module ActiveEnum
|
|
122
122
|
|
123
123
|
end
|
124
124
|
end
|
125
|
-
|
126
|
-
ActiveRecord::Base.send :include, ActiveEnum::Extensions
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module ActiveEnum
|
2
|
+
class Model < ActiveRecord::Base
|
3
|
+
set_table_name 'enums'
|
4
|
+
serialize :meta, Hash
|
5
|
+
end
|
6
|
+
|
7
|
+
module Storage
|
8
|
+
class ActiveRecordStore < AbstractStore
|
9
|
+
def initialize(enum_class, order)
|
10
|
+
super
|
11
|
+
@values = values_from_db
|
12
|
+
end
|
13
|
+
|
14
|
+
def set(id, name)
|
15
|
+
check_duplicate id, name
|
16
|
+
values << [id, name]
|
17
|
+
sort!
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_by_id(id)
|
21
|
+
values.assoc(id)
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_by_name(name)
|
25
|
+
values.rassoc(name.to_s) || values.rassoc(name.to_s.titleize)
|
26
|
+
end
|
27
|
+
|
28
|
+
def values
|
29
|
+
@values
|
30
|
+
end
|
31
|
+
|
32
|
+
def check_duplicate(id, name)
|
33
|
+
if get_by_id(id) || get_by_name(name)
|
34
|
+
raise ActiveEnum::DuplicateValue
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def sort!
|
39
|
+
return if @order == :as_defined
|
40
|
+
case @order
|
41
|
+
when :asc
|
42
|
+
values.sort! {|a,b| a[0] <=> b[0] }
|
43
|
+
when :desc
|
44
|
+
values.sort! {|a,b| b[0] <=> a[0] }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def order_clause
|
49
|
+
@order_clause ||= case @order
|
50
|
+
when :asc
|
51
|
+
'enum_id ASC'
|
52
|
+
when :desc
|
53
|
+
'enum_id DESC'
|
54
|
+
else
|
55
|
+
'modified_at ASC'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def values_from_db
|
60
|
+
ActiveEnum::Model.all(:conditions => {:enum_type => @enum.to_s}, :order => order_clause).map {|r| [r.enum_id, r.name] }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/active_enum/version.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
module ActiveEnum
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
desc "Copy ActiveEnum default files"
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
6
|
+
class_option :template_engine
|
7
|
+
|
8
|
+
def copy_initializers
|
9
|
+
copy_file 'active_enum.rb', 'config/initializers/active_enum.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Form helper integration
|
2
|
+
# require 'active_enum/form_helpers/simple_form'
|
3
|
+
# require 'active_enum/form_helpers/formtastic
|
4
|
+
|
5
|
+
ActiveEnum.setup do |config|
|
6
|
+
|
7
|
+
# Extend classes to add enumerate method
|
8
|
+
config.extend_classes = [ ActiveRecord::Base ]
|
9
|
+
|
10
|
+
# Return name string as value for attribute method
|
11
|
+
# config.use_name_as_value = false
|
12
|
+
|
13
|
+
# Storage of values
|
14
|
+
# config.storage = :memory
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
# ActiveEnum.define do
|
19
|
+
#
|
20
|
+
# enum(:enum_name) do
|
21
|
+
# value 1 => 'Name'
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'active_enum/storage/active_record_store'
|
3
|
+
|
4
|
+
class TestARStoreEnum < ActiveEnum::Base; end
|
5
|
+
class TestOtherAREnum < ActiveEnum::Base; end
|
6
|
+
|
7
|
+
describe ActiveEnum::Storage::ActiveRecordStore do
|
8
|
+
attr_accessor :store
|
9
|
+
|
10
|
+
context '#set' do
|
11
|
+
it 'should store value of id and name' do
|
12
|
+
store.set 1, 'Name 1'
|
13
|
+
store.values.should == [[1, 'Name 1']]
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should raise error if duplicate id' do
|
17
|
+
lambda {
|
18
|
+
store.set 1, 'Name 1'
|
19
|
+
store.set 1, 'Other Name'
|
20
|
+
}.should raise_error(ActiveEnum::DuplicateValue)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should raise error if duplicate name' do
|
24
|
+
lambda {
|
25
|
+
store.set 1, 'Name 1'
|
26
|
+
store.set 2, 'Name 1'
|
27
|
+
}.should raise_error(ActiveEnum::DuplicateValue)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should raise error if duplicate name matches title-case name' do
|
31
|
+
lambda {
|
32
|
+
store.set 1, 'Name 1'
|
33
|
+
store.set 2, 'name 1'
|
34
|
+
}.should raise_error(ActiveEnum::DuplicateValue)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should create a record for values' do
|
38
|
+
store.set 1, 'Name 1'
|
39
|
+
ActiveEnum::Model.count.should == 1
|
40
|
+
r = ActiveEnum::Model.first
|
41
|
+
r.enum_id.should == 1
|
42
|
+
r.name.should == 'Name 1'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "#values" do
|
47
|
+
it 'should return array of stored values' do
|
48
|
+
store.set 1, 'Name 1'
|
49
|
+
store.values.should == [[1, 'Name 1']]
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should return values for set enum only' do
|
53
|
+
alt_store.set 1, 'Other Name 1'
|
54
|
+
store.set 1, 'Name 1'
|
55
|
+
store.values.should == [[1, 'Name 1']]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "#get_by_id" do
|
60
|
+
it 'should return the value for a given id' do
|
61
|
+
store.set 1, 'Name 1'
|
62
|
+
store.get_by_id(1).should == [1, 'Name 1']
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should return nil when id not found' do
|
66
|
+
store.get_by_id(1).should be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should return value for correct enum' do
|
70
|
+
alt_store.set 1, 'Other Name 1'
|
71
|
+
store.set 1, 'Name 1'
|
72
|
+
store.get_by_id(1).should == [1, 'Name 1']
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "#get_by_name" do
|
77
|
+
it 'should return the value for a given name' do
|
78
|
+
store.set 1, 'Name 1'
|
79
|
+
store.get_by_name('Name 1').should == [1, 'Name 1']
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should return the value with title-cased name for a given lowercase name' do
|
83
|
+
store.set 1, 'Name 1'
|
84
|
+
store.get_by_name('name 1').should == [1, 'Name 1']
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should return nil when name not found' do
|
88
|
+
store.get_by_name('test name').should be_nil
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should return value for correct enum' do
|
92
|
+
alt_store.set 1, 'Other Name 1'
|
93
|
+
store.set 1, 'Name 1'
|
94
|
+
store.get_by_name('Name 1').should == [1, 'Name 1']
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "sort!" do
|
99
|
+
it 'should sort values ascending when passed :asc' do
|
100
|
+
@order = :asc
|
101
|
+
store.set 2, 'Name 2'
|
102
|
+
store.set 1, 'Name 1'
|
103
|
+
store.values.should == [[1,'Name 1'], [2, 'Name 2']]
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should sort values descending when passed :desc' do
|
107
|
+
@order = :desc
|
108
|
+
store.set 1, 'Name 1'
|
109
|
+
store.set 2, 'Name 2'
|
110
|
+
store.values.should == [[2, 'Name 2'], [1,'Name 1']]
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should not sort values when passed :as_defined' do
|
114
|
+
@order = :as_defined
|
115
|
+
store.set 1, 'Name 1'
|
116
|
+
store.set 3, 'Name 3'
|
117
|
+
store.set 2, 'Name 2'
|
118
|
+
store.values.should == [[1,'Name 1'], [3,'Name 3'], [2, 'Name 2']]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
after do
|
123
|
+
ActiveEnum::Model.delete_all
|
124
|
+
end
|
125
|
+
|
126
|
+
def store
|
127
|
+
@store ||= ActiveEnum::Storage::ActiveRecordStore.new(TestARStoreEnum, @order)
|
128
|
+
end
|
129
|
+
|
130
|
+
def alt_store
|
131
|
+
@alt_store ||= ActiveEnum::Storage::ActiveRecordStore.new(TestOtherAREnum, :asc)
|
132
|
+
end
|
133
|
+
end
|
data/spec/active_enum_spec.rb
CHANGED
@@ -2,19 +2,44 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe "Bulk enum definitions" do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
context ".define" do
|
6
|
+
it 'should define enum constants using block' do
|
7
|
+
ActiveEnum.define do
|
8
|
+
enum(:foo) do
|
9
|
+
value :id => 1, :name => 'Foo 1'
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
enum(:bar) do
|
13
|
+
value :id => 1, :name => 'Bar 1'
|
14
|
+
end
|
13
15
|
end
|
16
|
+
Foo.all.should == [[1,'Foo 1']]
|
17
|
+
Bar.all.should == [[1,'Bar 1']]
|
14
18
|
end
|
19
|
+
end
|
15
20
|
|
16
|
-
|
17
|
-
|
21
|
+
context ".setup" do
|
22
|
+
before :all do
|
23
|
+
@original = ActiveEnum.use_name_as_value
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should pass module into block as configuration object' do
|
27
|
+
ActiveEnum.use_name_as_value.should be_false
|
28
|
+
ActiveEnum.setup {|config| config.use_name_as_value = true }
|
29
|
+
ActiveEnum.use_name_as_value.should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
after :all do
|
33
|
+
ActiveEnum.use_name_as_value = @original
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context ".extend_classes" do
|
38
|
+
it 'should add enumerate extensions to given classes' do
|
39
|
+
ActiveEnum.extend_classes = [ActiveRecord::Base, NotActiveRecord]
|
40
|
+
ActiveRecord::Base.should respond_to(:enumerate)
|
41
|
+
NotActiveRecord.should respond_to(:enumerate)
|
42
|
+
end
|
18
43
|
end
|
19
44
|
|
20
45
|
it 'should use the memory store by default' do
|
data/spec/schema.rb
CHANGED
@@ -12,4 +12,15 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
12
12
|
t.string :name
|
13
13
|
end
|
14
14
|
|
15
|
+
create_table :enums, :force => true do |t|
|
16
|
+
t.integer :enum_id
|
17
|
+
t.string :name
|
18
|
+
t.string :enum_type
|
19
|
+
t.string :meta
|
20
|
+
t.datetime :modified_at
|
21
|
+
end
|
22
|
+
add_index :enums, [:enum_id, :enum_type], :unique => true
|
23
|
+
add_index :enums, [:name, :enum_type]
|
24
|
+
add_index :enums, [:modified_at, :enum_type]
|
25
|
+
|
15
26
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -19,6 +19,8 @@ ActiveRecord::Migration.verbose = false
|
|
19
19
|
ActiveRecord::Base.establish_connection({:adapter => 'sqlite3', :database => ':memory:'})
|
20
20
|
ActiveRecord::Base.logger = Logger.new('/dev/null')
|
21
21
|
|
22
|
+
ActiveEnum.extend_classes = [ActiveRecord::Base]
|
23
|
+
|
22
24
|
require 'schema'
|
23
25
|
|
24
26
|
class Person < ActiveRecord::Base; end
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 9
|
9
|
+
- 0
|
10
|
+
version: 0.9.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adam Meehan
|
@@ -15,7 +15,7 @@ autorequire: active_enum
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-11 00:00:00 +10:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -39,14 +39,18 @@ files:
|
|
39
39
|
- lib/active_enum/form_helpers/formtastic.rb
|
40
40
|
- lib/active_enum/form_helpers/simple_form.rb
|
41
41
|
- lib/active_enum/storage/abstract_store.rb
|
42
|
+
- lib/active_enum/storage/active_record_store.rb
|
42
43
|
- lib/active_enum/storage/memory_store.rb
|
43
44
|
- lib/active_enum/version.rb
|
44
45
|
- lib/active_enum.rb
|
46
|
+
- lib/generators/active_enum/install_generator.rb
|
47
|
+
- lib/generators/active_enum/templates/active_enum.rb
|
45
48
|
- spec/active_enum/acts_as_enum_spec.rb
|
46
49
|
- spec/active_enum/base_spec.rb
|
47
50
|
- spec/active_enum/extensions_spec.rb
|
48
51
|
- spec/active_enum/form_helpers/formtastic_spec.rb
|
49
52
|
- spec/active_enum/form_helpers/simple_form_spec.rb
|
53
|
+
- spec/active_enum/storage/active_record_store_spec.rb
|
50
54
|
- spec/active_enum/storage/memory_store_spec.rb
|
51
55
|
- spec/active_enum_spec.rb
|
52
56
|
- spec/schema.rb
|