ar-enums 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/Gemfile.lock +71 -38
- data/Guardfile +2 -18
- data/README.md +129 -0
- data/Rakefile +1 -1
- data/ar_enums.gemspec +2 -4
- data/examples/internal_enums.rb +8 -10
- data/lib/ar_enums/version.rb +1 -1
- data/spec/ar_enums/base_spec.rb +11 -11
- data/spec/ar_enums/enum_definition_spec.rb +49 -49
- data/spec/ar_enums/factory_spec.rb +15 -15
- data/spec/spec_helper.rb +6 -3
- metadata +11 -26
- data/.autotest +0 -2
- data/.rbenv-version +0 -1
- data/README.rdoc +0 -122
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c0a162df9f114bb7f98a9e3677f9c9f120410fa
|
4
|
+
data.tar.gz: 3b5e730a99f090bd33d8358ae7f0c956b56de9b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0617d1dc6e15212c45ca6971755123e92f33221ce241369737b7f5cc800c087fe44e97b6e310f2c89fc137a4abf9d150c16f04604a7151adb5e9507b851da9e0
|
7
|
+
data.tar.gz: 0ff182905b261870a7b4f84fd86f5641894a9d1e1d3ee4f4262cb7606d8aa6db52377c85acd4a62d4bc4deaf13b12944889dd555c359445da80042b0d4ce641e
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.1
|
data/Gemfile.lock
CHANGED
@@ -1,52 +1,82 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ar-enums (2.0.
|
4
|
+
ar-enums (2.0.2)
|
5
5
|
activerecord (>= 3.1.0)
|
6
|
-
rake
|
7
6
|
|
8
7
|
GEM
|
9
8
|
remote: http://rubygems.org/
|
10
9
|
specs:
|
11
|
-
activemodel (
|
12
|
-
activesupport (=
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
i18n (
|
20
|
-
json (~> 1.7, >= 1.7.7)
|
10
|
+
activemodel (5.2.0)
|
11
|
+
activesupport (= 5.2.0)
|
12
|
+
activerecord (5.2.0)
|
13
|
+
activemodel (= 5.2.0)
|
14
|
+
activesupport (= 5.2.0)
|
15
|
+
arel (>= 9.0)
|
16
|
+
activesupport (5.2.0)
|
17
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
|
+
i18n (>= 0.7, < 2)
|
21
19
|
minitest (~> 5.1)
|
22
|
-
thread_safe (~> 0.1)
|
23
20
|
tzinfo (~> 1.1)
|
24
|
-
arel (
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
guard
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
21
|
+
arel (9.0.0)
|
22
|
+
coderay (1.1.2)
|
23
|
+
concurrent-ruby (1.0.5)
|
24
|
+
diff-lcs (1.3)
|
25
|
+
ffi (1.9.25)
|
26
|
+
formatador (0.2.5)
|
27
|
+
guard (2.14.2)
|
28
|
+
formatador (>= 0.2.4)
|
29
|
+
listen (>= 2.7, < 4.0)
|
30
|
+
lumberjack (>= 1.0.12, < 2.0)
|
31
|
+
nenv (~> 0.1)
|
32
|
+
notiffany (~> 0.0)
|
33
|
+
pry (>= 0.9.12)
|
34
|
+
shellany (~> 0.0)
|
35
|
+
thor (>= 0.18.1)
|
36
|
+
guard-compat (1.2.1)
|
37
|
+
guard-rspec (4.7.3)
|
38
|
+
guard (~> 2.1)
|
39
|
+
guard-compat (~> 1.1)
|
40
|
+
rspec (>= 2.99.0, < 4.0)
|
41
|
+
i18n (1.0.1)
|
42
|
+
concurrent-ruby (~> 1.0)
|
43
|
+
listen (3.1.5)
|
44
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
45
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
46
|
+
ruby_dep (~> 1.2)
|
47
|
+
lumberjack (1.0.13)
|
48
|
+
method_source (0.9.0)
|
49
|
+
minitest (5.11.3)
|
50
|
+
nenv (0.3.0)
|
51
|
+
notiffany (0.1.1)
|
52
|
+
nenv (~> 0.1)
|
53
|
+
shellany (~> 0.0)
|
54
|
+
pry (0.11.3)
|
55
|
+
coderay (~> 1.1.0)
|
56
|
+
method_source (~> 0.9.0)
|
36
57
|
rake (10.3.2)
|
37
|
-
rb-fsevent (0.
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
rspec-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
58
|
+
rb-fsevent (0.10.3)
|
59
|
+
rb-inotify (0.9.10)
|
60
|
+
ffi (>= 0.5.0, < 2)
|
61
|
+
rspec (3.7.0)
|
62
|
+
rspec-core (~> 3.7.0)
|
63
|
+
rspec-expectations (~> 3.7.0)
|
64
|
+
rspec-mocks (~> 3.7.0)
|
65
|
+
rspec-core (3.7.1)
|
66
|
+
rspec-support (~> 3.7.0)
|
67
|
+
rspec-expectations (3.7.0)
|
68
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
69
|
+
rspec-support (~> 3.7.0)
|
70
|
+
rspec-mocks (3.7.0)
|
71
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
72
|
+
rspec-support (~> 3.7.0)
|
73
|
+
rspec-support (3.7.1)
|
74
|
+
ruby_dep (1.5.0)
|
75
|
+
shellany (0.0.1)
|
46
76
|
sqlite3 (1.3.9)
|
47
|
-
thor (0.
|
48
|
-
thread_safe (0.3.
|
49
|
-
tzinfo (1.2.
|
77
|
+
thor (0.20.0)
|
78
|
+
thread_safe (0.3.6)
|
79
|
+
tzinfo (1.2.5)
|
50
80
|
thread_safe (~> 0.1)
|
51
81
|
|
52
82
|
PLATFORMS
|
@@ -55,6 +85,9 @@ PLATFORMS
|
|
55
85
|
DEPENDENCIES
|
56
86
|
ar-enums!
|
57
87
|
guard-rspec
|
58
|
-
|
88
|
+
rake
|
59
89
|
rspec
|
60
90
|
sqlite3 (>= 1.3.4)
|
91
|
+
|
92
|
+
BUNDLED WITH
|
93
|
+
1.16.0
|
data/Guardfile
CHANGED
@@ -1,21 +1,5 @@
|
|
1
|
-
|
2
|
-
# More info at https://github.com/guard/guard#readme
|
3
|
-
|
4
|
-
guard 'rspec', :version => 2 do
|
1
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
5
2
|
watch(%r{^spec/.+_spec\.rb$})
|
6
|
-
watch(%r{^lib/(.+)\.rb$}) { |m| "spec
|
3
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
4
|
watch('spec/spec_helper.rb') { "spec" }
|
8
|
-
|
9
|
-
# Rails example
|
10
|
-
watch(%r{^spec/.+_spec\.rb$})
|
11
|
-
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
12
|
-
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
13
|
-
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
14
|
-
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
15
|
-
watch('spec/spec_helper.rb') { "spec" }
|
16
|
-
watch('config/routes.rb') { "spec/routing" }
|
17
|
-
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
18
|
-
# Capybara request specs
|
19
|
-
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
20
5
|
end
|
21
|
-
|
data/README.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# ar-enums
|
2
|
+
|
3
|
+
This is a simple solution for defining enumerations in your Rails models.
|
4
|
+
|
5
|
+
[![Build Status](https://travis-ci.org/eeng/ar-enums.svg?branch=master)](https://travis-ci.org/eeng/ar-enums)
|
6
|
+
|
7
|
+
## Description
|
8
|
+
|
9
|
+
It provides two forms of enumerations:
|
10
|
+
* Internal, i.e. defined within the owner of the enum, for the simple cases.
|
11
|
+
* External, i.e. defined on it's own class, for the complex ones.
|
12
|
+
|
13
|
+
In both cases the enum values are stored in-memory. Let's see some examples of both kinds.
|
14
|
+
|
15
|
+
## Internal enumerations
|
16
|
+
|
17
|
+
Can be defined in three flavours:
|
18
|
+
|
19
|
+
### Array of values style
|
20
|
+
|
21
|
+
This is the simplest and probably the most frecuent case:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
class TrafficLight < ActiveRecord::Base
|
25
|
+
enum :state, %w[red green yellow]
|
26
|
+
end
|
27
|
+
|
28
|
+
tl = TrafficLight.new(:state => :green)
|
29
|
+
tl.state # => #<TrafficLight::State @name="green", @id=2>
|
30
|
+
tl.state_id # => 2
|
31
|
+
tl.state.green? # => true
|
32
|
+
```
|
33
|
+
|
34
|
+
As you can see each enum value is an instance of a dinamically generated class (which inherits from ArEnums::Base) and has an ordinal value, id, autogenerated staring on 1.
|
35
|
+
|
36
|
+
The enumerations array is accessed with a class method:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
TrafficLight.states # => [#<TrafficLight::State @name="red", @id=1>, #<TrafficLight::State @name="green", @id=2>, ...]
|
40
|
+
```
|
41
|
+
|
42
|
+
By default when `#to_s` is called on a Enum instance it returns the name titleized, but this behaviour can be overrided. See Displaying Enums section below.
|
43
|
+
|
44
|
+
### Array of hashes style
|
45
|
+
|
46
|
+
This allows you to define new columns in the Enum value. If the :id is not specified is generated for you.
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
class TrafficLight < ActiveRecord::Base
|
50
|
+
enum :state, [
|
51
|
+
{ :name => :red, :stop_traffic => true, :rgb => 0xF00 },
|
52
|
+
{ :name => :green, :stop_traffic => false, :rgb => 0x0F0 }
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
tl = TrafficLight.new(:state => :green)
|
57
|
+
tl.state_id # => 2
|
58
|
+
tl.state.stop_traffic # => false
|
59
|
+
tl.state.rgb # => 0x0F0
|
60
|
+
```
|
61
|
+
|
62
|
+
### Block style
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
class TrafficLight < ActiveRecord::Base
|
66
|
+
enum :state do
|
67
|
+
red :stop_traffic => true, :rgb => 0xF00
|
68
|
+
green :stop_traffic => false, :rgb => 0x0F0
|
69
|
+
end
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
## External enumerations
|
74
|
+
|
75
|
+
When you have shared enumerations or just don't want to clutter the owner model with enums definitions,
|
76
|
+
the enumeration can be on it's own class, as the State enum in the following example:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
class TrafficLight < ActiveRecord::Base
|
80
|
+
enum :state
|
81
|
+
end
|
82
|
+
|
83
|
+
class State < ArEnums::Base
|
84
|
+
enumeration do
|
85
|
+
red :stop_traffic => true, :rgb => 0xF00, :desc => 'Rojo'
|
86
|
+
green :stop_traffic => false, :rgb => 0x0F0, :desc => 'Verde'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
State[:red] # => #<State @name="red", @id=1, ...>
|
91
|
+
State[:red].to_s # => "Rojo"
|
92
|
+
```
|
93
|
+
|
94
|
+
Note the block style sintax is exactly the same as in the internal enumerations. In fact any of the 3 styles mencioned above can be used on external enumerations.
|
95
|
+
|
96
|
+
Also note the `#to_s` by default return the value of the `:desc` column. Of course you can override the `#to_s` method as usual.
|
97
|
+
|
98
|
+
Then you can access the enumerations collection from both places:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
TrafficLight.states # => [#<State @name="red", @id=1, ...>, #<State @name="green", @id=2, ...>]
|
102
|
+
States.all # => [#<State @name="red", @id=1, ...>, #<State @name="green", @id=2, ...>]
|
103
|
+
```
|
104
|
+
|
105
|
+
The `enum` method accept a `:class_method` option similar to the one in `belongs_to` and others to specify the class of the enum.
|
106
|
+
|
107
|
+
## Displaying Enums
|
108
|
+
|
109
|
+
In the array of values style the default is the name titleized but you can pass a `:label` options to override:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
class TrafficLight < ActiveRecord::Base
|
113
|
+
enum :state, %w[red green yellow], :label => :upcase
|
114
|
+
end
|
115
|
+
|
116
|
+
TrafficLight.states.map(&:to_s) # => ["RED", "GREEN", "YELLOW"]
|
117
|
+
```
|
118
|
+
|
119
|
+
If you use the block o array of hashes sintax and add a `:desc` column it will be used as `#to_s`, unless a `:label` option is passed.
|
120
|
+
|
121
|
+
## Note on Patches/Pull Requests
|
122
|
+
|
123
|
+
* Fork the project.
|
124
|
+
* Make your feature addition or bug fix.
|
125
|
+
* Add tests for it. This is important so I don't break it in a
|
126
|
+
future version unintentionally.
|
127
|
+
* Commit, do not mess with rakefile, version, or history.
|
128
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
129
|
+
* Send me a pull request. Bonus points for topic branches.
|
data/Rakefile
CHANGED
data/ar_enums.gemspec
CHANGED
@@ -16,12 +16,10 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
18
|
s.require_paths = ["lib"]
|
19
|
-
|
19
|
+
|
20
20
|
s.add_development_dependency "rspec"
|
21
21
|
s.add_development_dependency "guard-rspec"
|
22
|
-
s.add_development_dependency "rb-fsevent"
|
23
|
-
# s.add_development_dependency "ruby-debug19"
|
24
22
|
s.add_development_dependency "sqlite3", ">= 1.3.4"
|
23
|
+
s.add_development_dependency "rake"
|
25
24
|
s.add_dependency "activerecord", ">= 3.1.0"
|
26
|
-
s.add_dependency "rake"
|
27
25
|
end
|
data/examples/internal_enums.rb
CHANGED
@@ -1,27 +1,25 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'active_record'
|
3
1
|
require 'ar-enums'
|
4
2
|
|
5
|
-
ActiveRecord::Base.establish_connection(:
|
3
|
+
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
6
4
|
load(File.dirname(__FILE__) + "/../spec/schema.rb")
|
7
5
|
|
8
6
|
class TrafficLight < ActiveRecord::Base
|
9
7
|
enum :state, %w[red green yellow]
|
10
8
|
end
|
11
9
|
|
12
|
-
tl = TrafficLight.new(:
|
10
|
+
tl = TrafficLight.new(state: :green)
|
13
11
|
p tl.state # => #<TrafficLight::State @name="green", @id=2>
|
14
|
-
p tl.state_id # => 2
|
12
|
+
p tl.state_id # => 2
|
15
13
|
p TrafficLight.states.map(&:to_s)
|
16
14
|
|
17
15
|
# class TrafficLight < ActiveRecord::Base
|
18
16
|
# enum :state, [
|
19
|
-
# { :
|
20
|
-
# { :
|
17
|
+
# { name: :red, stop_traffic: true, rgb: 0xF00 },
|
18
|
+
# { name: :green, stop_traffic: false, rgb: 0x0F0 }
|
21
19
|
# ]
|
22
20
|
# end
|
23
|
-
#
|
24
|
-
# tl = TrafficLight.new(:
|
25
|
-
# p tl.state_id # => 2
|
21
|
+
#
|
22
|
+
# tl = TrafficLight.new(state: :green)
|
23
|
+
# p tl.state_id # => 2
|
26
24
|
# p tl.state.stop_traffic # => false
|
27
25
|
# p tl.state.rgb # => 0x0F0
|
data/lib/ar_enums/version.rb
CHANGED
data/spec/ar_enums/base_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe "Enum" do
|
|
4
4
|
it "should provide :to_sym method returning name as symbols" do
|
5
5
|
ArEnums::Base.new(name: :green).to_sym.should == :green
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
it "should store extra columns as a hash without the :enum_class that is passed from other classes" do
|
9
9
|
ArEnums::Base.new(name: :green, factor: 1.5, enum_class: Class.new).extra_columns.should == { factor: 1.5 }
|
10
10
|
end
|
@@ -17,30 +17,30 @@ describe "Enum" do
|
|
17
17
|
green rgb: 0x0F0
|
18
18
|
blue rgb: 0x00F
|
19
19
|
end
|
20
|
-
end
|
20
|
+
end
|
21
21
|
|
22
22
|
define_model_class 'State', 'ArEnums::Base' do
|
23
23
|
enumeration do
|
24
24
|
on id: 80
|
25
25
|
off id: 90
|
26
26
|
end
|
27
|
-
end
|
27
|
+
end
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it "should provide :all method to access the enums" do
|
31
31
|
Color.all[0].should be_enum_with(name: 'red', rgb: 0xF00)
|
32
32
|
Color.all[1].should be_enum_with(name: 'green', rgb: 0x0F0)
|
33
33
|
State.all[0].should be_enum_with(name: 'on', id: 80)
|
34
34
|
State.all[1].should be_enum_with(name: 'off', id: 90)
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
it "should provide [] method to access the enums" do
|
38
38
|
Color[:red].should be_enum_with(name: 'red')
|
39
39
|
Color['green'].should be_enum_with(name: 'green')
|
40
40
|
Color[2].should be_enum_with(name: 'green')
|
41
41
|
end
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
context "finders" do
|
45
45
|
it "find_all_by_id" do
|
46
46
|
Color.find_all_by_id([1, 2, 3, 4]).should == Color.all
|
@@ -48,7 +48,7 @@ describe "Enum" do
|
|
48
48
|
Color.find_all_by_id([]).should == []
|
49
49
|
end
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
it "in? should check if == to any" do
|
53
53
|
define_model_class 'Color', 'ArEnums::Base' do
|
54
54
|
enumeration do
|
@@ -56,16 +56,16 @@ describe "Enum" do
|
|
56
56
|
green rgb: 0x0F0
|
57
57
|
blue rgb: 0x00F
|
58
58
|
end
|
59
|
-
end
|
60
|
-
|
59
|
+
end
|
60
|
+
|
61
61
|
Color[:red].should be_in :red, :blue
|
62
62
|
Color[:red].should be_in :green, :red, :blue
|
63
63
|
Color[:red].should be_in Color[:red]
|
64
64
|
Color[:red].should_not be_in :blue
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
it "should work with sets" do
|
68
|
-
Set.new([Color[:red]]).intersection(Set.new([Color[:red].dup])).should
|
68
|
+
Set.new([Color[:red]]).intersection(Set.new([Color[:red].dup])).size.should == 1
|
69
69
|
end
|
70
70
|
|
71
71
|
it "should be sortable" do
|
@@ -10,60 +10,60 @@ describe "Internal enumerations" do
|
|
10
10
|
before do
|
11
11
|
define_traffic_light :state, %w[red green yellow]
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
context "getter and setter" do
|
15
15
|
it "getter should return an Enum" do
|
16
|
-
TrafficLight.new(:
|
16
|
+
TrafficLight.new(state_id: 3).state.should be_enum_with(id: 3, name: 'yellow')
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should store ordinal by default as foreign key" do
|
20
|
-
TrafficLight.new(:
|
20
|
+
TrafficLight.new(state: :green).state_id.should == 2
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should store nil if enum doesn't exists" do
|
24
|
-
TrafficLight.new(:
|
24
|
+
TrafficLight.new(state: :black).state_id.should be_nil
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should allow to set enum with symbol" do
|
28
|
-
TrafficLight.new(:
|
29
|
-
TrafficLight.new(:
|
28
|
+
TrafficLight.new(state: :red).state.should == :red
|
29
|
+
TrafficLight.new(state: :green).state.should == :green
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should allow to set enum with string" do
|
33
|
-
TrafficLight.new(:
|
34
|
-
TrafficLight.new(:
|
33
|
+
TrafficLight.new(state: 'red').state.should == :red
|
34
|
+
TrafficLight.new(state: 'green').state.should == :green
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should allow to set enum with ordinal" do
|
38
|
-
TrafficLight.new(:
|
39
|
-
TrafficLight.new(:
|
40
|
-
end
|
38
|
+
TrafficLight.new(state_id: 1).state.should == :red
|
39
|
+
TrafficLight.new(state_id: 2).state.should == :green
|
40
|
+
end
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
context "options" do
|
44
44
|
it "should pass the options to the factory" do
|
45
|
-
define_traffic_light :state, %w[green red], :
|
46
|
-
TrafficLight.new(:
|
47
|
-
TrafficLight.new(:
|
45
|
+
define_traffic_light :state, %w[green red], label: :upcase
|
46
|
+
TrafficLight.new(state: :green).state.to_s.should == 'GREEN'
|
47
|
+
TrafficLight.new(state: :red).state.to_s.should == 'RED'
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
context "question methods" do
|
52
52
|
before do
|
53
53
|
define_traffic_light :state, %w[green red]
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
it "should provide question method" do
|
57
|
-
TrafficLight.new(:
|
58
|
-
TrafficLight.new(:
|
59
|
-
TrafficLight.new(:
|
60
|
-
TrafficLight.new(:
|
57
|
+
TrafficLight.new(state: :green).state.should be_green
|
58
|
+
TrafficLight.new(state: :green).state.should_not be_red
|
59
|
+
TrafficLight.new(state: :red).state.should_not be_green
|
60
|
+
TrafficLight.new(state: :red).state.should be_red
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
it "should raise error if tested with inexistant enum" do
|
64
|
-
lambda { TrafficLight.new(:
|
64
|
+
lambda { TrafficLight.new(state: :green).state.blue? }.should raise_error(NameError)
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
it "block style should also provide question method" do
|
68
68
|
define_model_class 'TrafficLight' do
|
69
69
|
enum :state do
|
@@ -71,11 +71,11 @@ describe "Internal enumerations" do
|
|
71
71
|
red
|
72
72
|
end
|
73
73
|
end
|
74
|
-
TrafficLight.new(:
|
75
|
-
TrafficLight.new(:
|
74
|
+
TrafficLight.new(state: :green).state.should be_green
|
75
|
+
TrafficLight.new(state: :green).state.should_not be_red
|
76
76
|
end
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
it "should be instances of a new subclass of Enum" do
|
80
80
|
TrafficLight.states.first.should be_a(TrafficLight::State)
|
81
81
|
end
|
@@ -89,26 +89,26 @@ describe "External enumerations" do
|
|
89
89
|
tx
|
90
90
|
end
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
define_model_class 'Country' do
|
94
94
|
enum :state
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
define_model_class 'TrafficLightState', 'ArEnums::Base' do
|
98
98
|
enumeration do
|
99
|
-
green :
|
100
|
-
red :
|
99
|
+
green rgb: 0x0F0
|
100
|
+
red rgb: 0xF00
|
101
101
|
end
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
define_model_class 'TrafficLight' do
|
105
|
-
enum :state, :
|
105
|
+
enum :state, class_name: 'TrafficLightState'
|
106
106
|
end
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
context "enums creation" do
|
110
110
|
it "should allow to define enumerations on it's own class" do
|
111
|
-
TrafficLight.new(:
|
111
|
+
TrafficLight.new(state: :red).state.should be_enum_with(name: 'red', rgb: 0xF00, id: 2)
|
112
112
|
end
|
113
113
|
|
114
114
|
it "should be posible to access all enums from withing the owner" do
|
@@ -118,34 +118,34 @@ describe "External enumerations" do
|
|
118
118
|
|
119
119
|
it "should accept :class_name options to override de class of the external enum" do
|
120
120
|
define_model_class 'TrafficLight' do
|
121
|
-
enum :state_on_weekdays, :
|
122
|
-
enum :state_on_weekends, :
|
121
|
+
enum :state_on_weekdays, class_name: 'TrafficLightState'
|
122
|
+
enum :state_on_weekends, class_name: 'TrafficLightState'
|
123
123
|
end
|
124
124
|
TrafficLight.state_on_weekdays.should equal(TrafficLightState.all)
|
125
125
|
TrafficLight.state_on_weekends.should equal(TrafficLightState.all)
|
126
|
-
end
|
127
|
-
|
126
|
+
end
|
127
|
+
|
128
128
|
it "external enums should be instances of the subclass of Enum" do
|
129
129
|
TrafficLightState.all.each { |s| s.should be_a(TrafficLightState) }
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
it "should be posible to define new methods in Enum subclass" do
|
133
133
|
define_model_class 'State', 'ArEnums::Base' do
|
134
134
|
enumeration do
|
135
|
-
green :
|
136
|
-
red :
|
135
|
+
green factor: 1
|
136
|
+
red factor: 2
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
def double_factor() factor * 2 end
|
140
|
-
end
|
140
|
+
end
|
141
141
|
State.all.map(&:double_factor).should == [2, 4]
|
142
|
-
end
|
143
|
-
|
142
|
+
end
|
143
|
+
|
144
144
|
it "should not define new constant form enum class" do
|
145
145
|
define_model_class 'TrafficLight' do
|
146
|
-
enum :estado, :
|
146
|
+
enum :estado, class_name: 'TrafficLightState'
|
147
147
|
end
|
148
|
-
|
149
|
-
end
|
148
|
+
lambda { TrafficLight.const_get(:Estado) }.should raise_error NameError
|
149
|
+
end
|
150
150
|
end
|
151
151
|
end
|
@@ -7,7 +7,7 @@ describe "Enums creation styles" do
|
|
7
7
|
add_option config, class_name: ArEnums::Base
|
8
8
|
ArEnums::Factory.make_enums *config, &block
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
context "array of values style" do
|
12
12
|
it "should generate ids" do
|
13
13
|
enums = make_enums %w[red green blue]
|
@@ -15,23 +15,23 @@ describe "Enums creation styles" do
|
|
15
15
|
enums[1].should be_enum_with(id: 2, name: 'green')
|
16
16
|
enums[2].should be_enum_with(id: 3, name: 'blue')
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it "default to_s should be name titleized" do
|
20
|
-
make_enums(%w[green red]).map(&:to_s).should == %w[Green Red]
|
20
|
+
make_enums(%w[green red]).map(&:to_s).should == %w[Green Red]
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should override default to_s" do
|
24
24
|
make_enums(%w[green red], label: :upcase).map(&:to_s).should == %w[GREEN RED]
|
25
25
|
end
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
context "array of hashes style" do
|
29
29
|
it "should accept ids if provided" do
|
30
30
|
enums = make_enums [{ id: 20, name: :red }, { id: 10, name: :green }]
|
31
31
|
enums[0].should be_enum_with(id: 20, name: 'red')
|
32
32
|
enums[1].should be_enum_with(id: 10, name: 'green')
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
it "should generate ids if not provided" do
|
36
36
|
enums = make_enums [{ name: :red }, { name: :green }]
|
37
37
|
enums[0].should be_enum_with(id: 1, name: 'red')
|
@@ -41,18 +41,18 @@ describe "Enums creation styles" do
|
|
41
41
|
it "default to_s should be :desc column" do
|
42
42
|
enums = make_enums [{ name: :red, desc: 'Rojo' }, { name: :green, desc: 'Verde' }]
|
43
43
|
enums.map(&:to_s).should == %w[Rojo Verde]
|
44
|
-
end
|
45
|
-
|
44
|
+
end
|
45
|
+
|
46
46
|
it ":label options can be a method to call on name" do
|
47
47
|
enums = make_enums [{ name: :red }, { name: :green }], label: :upcase
|
48
48
|
enums.map(&:to_s).should == %w[RED GREEN]
|
49
|
-
end
|
50
|
-
|
49
|
+
end
|
50
|
+
|
51
51
|
it ":label option can be a enum column" do
|
52
52
|
enums = make_enums [{ name: :red, title: 'Rojo' }, { name: :green, title: 'Verde' }], label: :title
|
53
53
|
enums.map(&:to_s).should == %w[Rojo Verde]
|
54
|
-
end
|
55
|
-
|
54
|
+
end
|
55
|
+
|
56
56
|
it "should accept extra columns" do
|
57
57
|
enums = make_enums [
|
58
58
|
{ name: :red, factor: 1.5, stop_traffic: true },
|
@@ -62,7 +62,7 @@ describe "Enums creation styles" do
|
|
62
62
|
enums.map(&:stop_traffic).should == [true, false]
|
63
63
|
end
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
context "block style" do
|
67
67
|
it "can be created with a block" do
|
68
68
|
enums = make_enums do
|
@@ -71,8 +71,8 @@ describe "Enums creation styles" do
|
|
71
71
|
end
|
72
72
|
enums[0].should be_enum_with(id: 1, name: 'red', rgb: 0xF00)
|
73
73
|
enums[1].should be_enum_with(id: 2, name: 'green', rgb: 0x0F0)
|
74
|
-
end
|
75
|
-
|
74
|
+
end
|
75
|
+
|
76
76
|
it "should accept :label option" do
|
77
77
|
enums = make_enums label: :title do
|
78
78
|
red title: 'Rojo'
|
@@ -80,7 +80,7 @@ describe "Enums creation styles" do
|
|
80
80
|
end
|
81
81
|
enums.map(&:to_s).should == %w[Rojo Verde]
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
it "should accept extra columns" do
|
85
85
|
enums = make_enums do
|
86
86
|
red factor: 1.5
|
data/spec/spec_helper.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
-
require 'rspec'
|
2
1
|
require 'ar-enums'
|
3
2
|
|
3
|
+
ActiveRecord::Migration.verbose = false
|
4
|
+
|
4
5
|
RSpec.configure do |config|
|
6
|
+
config.expect_with(:rspec) { |c| c.syntax = :should }
|
7
|
+
|
5
8
|
config.before :suite do
|
6
|
-
ActiveRecord::Base.establish_connection(:
|
9
|
+
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
7
10
|
load(File.dirname(__FILE__) + "/schema.rb")
|
8
11
|
end
|
9
|
-
|
12
|
+
|
10
13
|
def define_model_class(name = "TestClass", parent_class_name = "ActiveRecord::Base", &block)
|
11
14
|
ActiveSupport::Dependencies.send :remove_const, name rescue nil
|
12
15
|
eval("class #{name} < #{parent_class_name}; end", TOPLEVEL_BINDING)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar-enums
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emmanuel Nicolau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -39,33 +39,33 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: sqlite3
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 1.3.4
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 1.3.4
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: activerecord
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,20 +80,6 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 3.1.0
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rake
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
83
|
description:
|
98
84
|
email:
|
99
85
|
- emmanicolau@gmail.com
|
@@ -101,15 +87,14 @@ executables: []
|
|
101
87
|
extensions: []
|
102
88
|
extra_rdoc_files: []
|
103
89
|
files:
|
104
|
-
- ".autotest"
|
105
90
|
- ".gitignore"
|
106
|
-
- ".rbenv-version"
|
107
91
|
- ".rspec"
|
92
|
+
- ".ruby-version"
|
108
93
|
- Gemfile
|
109
94
|
- Gemfile.lock
|
110
95
|
- Guardfile
|
111
96
|
- LICENSE
|
112
|
-
- README.
|
97
|
+
- README.md
|
113
98
|
- Rakefile
|
114
99
|
- ar_enums.gemspec
|
115
100
|
- autotest/discover.rb
|
@@ -147,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
132
|
version: '0'
|
148
133
|
requirements: []
|
149
134
|
rubyforge_project: ar-enums
|
150
|
-
rubygems_version: 2.
|
135
|
+
rubygems_version: 2.5.1
|
151
136
|
signing_key:
|
152
137
|
specification_version: 4
|
153
138
|
summary: Provides a simple way for defining enumerations in ActiveRecord models
|
data/.autotest
DELETED
data/.rbenv-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.1.0
|
data/README.rdoc
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
= ar-enums
|
2
|
-
|
3
|
-
This is a simple solution for defining enumerations in your Rails models.
|
4
|
-
|
5
|
-
== Description
|
6
|
-
|
7
|
-
It provides two forms of enumerations:
|
8
|
-
* Internal, i.e. defined within the owner of the enum, for the simple cases.
|
9
|
-
* External, i.e. defined on it's own class, for the complex ones.
|
10
|
-
|
11
|
-
In both cases the enum values are stored in-memory. Let's see some examples of both kinds.
|
12
|
-
|
13
|
-
== Internal enumerations
|
14
|
-
|
15
|
-
Can be defined in three flavours:
|
16
|
-
|
17
|
-
=== Array of values style
|
18
|
-
|
19
|
-
This is the simplest and probably the most frecuent case:
|
20
|
-
|
21
|
-
class TrafficLight < ActiveRecord::Base
|
22
|
-
enum :state, %w[red green yellow]
|
23
|
-
end
|
24
|
-
|
25
|
-
tl = TrafficLight.new(:state => :green)
|
26
|
-
tl.state # => #<TrafficLight::State @name="green", @id=2>
|
27
|
-
tl.state_id # => 2
|
28
|
-
tl.state.green? # => true
|
29
|
-
|
30
|
-
As you can see each enum value is an instance of a dinamically generated class (which inherits from ArEnums::Base) and has an ordinal value, id, autogenerated staring on 1.
|
31
|
-
|
32
|
-
The enumerations array is accessed with a class method:
|
33
|
-
|
34
|
-
TrafficLight.states # => [#<TrafficLight::State @name="red", @id=1>, #<TrafficLight::State @name="green", @id=2>, ...]
|
35
|
-
|
36
|
-
By default when <tt>#to_s</tt> is called on a Enum instance it returns the name titleized, but this behaviour can be overrided. See Displaying Enums section below.
|
37
|
-
|
38
|
-
=== Array of hashes style
|
39
|
-
|
40
|
-
This allows you to define new columns in the Enum value. If the :id is not specified is generated for you.
|
41
|
-
|
42
|
-
class TrafficLight < ActiveRecord::Base
|
43
|
-
enum :state, [
|
44
|
-
{ :name => :red, :stop_traffic => true, :rgb => 0xF00 },
|
45
|
-
{ :name => :green, :stop_traffic => false, :rgb => 0x0F0 }
|
46
|
-
]
|
47
|
-
end
|
48
|
-
|
49
|
-
tl = TrafficLight.new(:state => :green)
|
50
|
-
tl.state_id # => 2
|
51
|
-
tl.state.stop_traffic # => false
|
52
|
-
tl.state.rgb # => 0x0F0
|
53
|
-
|
54
|
-
=== Block style
|
55
|
-
|
56
|
-
class TrafficLight < ActiveRecord::Base
|
57
|
-
enum :state do
|
58
|
-
red :stop_traffic => true, :rgb => 0xF00
|
59
|
-
green :stop_traffic => false, :rgb => 0x0F0
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
== External enumerations
|
64
|
-
|
65
|
-
When you have shared enumerations or just don't want to clutter the owner model with enums definitions,
|
66
|
-
the enumeration can be on it's own class, as the State enum in the following example:
|
67
|
-
|
68
|
-
class TrafficLight < ActiveRecord::Base
|
69
|
-
enum :state
|
70
|
-
end
|
71
|
-
|
72
|
-
class State < ArEnums::Base
|
73
|
-
enumeration do
|
74
|
-
red :stop_traffic => true, :rgb => 0xF00, :desc => 'Rojo'
|
75
|
-
green :stop_traffic => false, :rgb => 0x0F0, :desc => 'Verde'
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
State[:red] # => #<State @name="red", @id=1, ...>
|
80
|
-
State[:red].to_s # => "Rojo"
|
81
|
-
|
82
|
-
Note the block style sintax is exactly the same as in the internal enumerations. In fact any of the 3 styles mencioned above can be used on external enumerations.
|
83
|
-
|
84
|
-
Also note the <tt>#to_s</tt> by default return the value of the <tt>:desc</tt> column. Of course you can override the <tt>#to_s</tt> method as usual.
|
85
|
-
|
86
|
-
Then you can access the enumerations collection from both places:
|
87
|
-
|
88
|
-
TrafficLight.states # => [#<State @name="red", @id=1, ...>, #<State @name="green", @id=2, ...>]
|
89
|
-
States.all # => [#<State @name="red", @id=1, ...>, #<State @name="green", @id=2, ...>]
|
90
|
-
|
91
|
-
The <tt>enum</tt> method accept a <tt>:class_method</tt> option similar to the one in <tt>belongs_to</tt> and others to specify the class of the enum.
|
92
|
-
|
93
|
-
== Displaying Enums
|
94
|
-
|
95
|
-
In the array of values style the default is the name titleized but you can pass a <tt>:label</tt> options to override:
|
96
|
-
|
97
|
-
class TrafficLight < ActiveRecord::Base
|
98
|
-
enum :state, %w[red green yellow], :label => :upcase
|
99
|
-
end
|
100
|
-
|
101
|
-
TrafficLight.states.map(&:to_s) # => ["RED", "GREEN", "YELLOW"]
|
102
|
-
|
103
|
-
If you use the block o array of hashes sintax and add a <tt>:desc</tt> column it will be used as <tt>#to_s</tt>, unless a <tt>:label</tt> option is passed.
|
104
|
-
|
105
|
-
== TODO
|
106
|
-
|
107
|
-
* Remove the dependency with ActiveRecord so it can be used outside Rails.
|
108
|
-
* Allow to store enums in the database.
|
109
|
-
|
110
|
-
== Note on Patches/Pull Requests
|
111
|
-
|
112
|
-
* Fork the project.
|
113
|
-
* Make your feature addition or bug fix.
|
114
|
-
* Add tests for it. This is important so I don't break it in a
|
115
|
-
future version unintentionally.
|
116
|
-
* Commit, do not mess with rakefile, version, or history.
|
117
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
118
|
-
* Send me a pull request. Bonus points for topic branches.
|
119
|
-
|
120
|
-
== Copyright
|
121
|
-
|
122
|
-
Copyright (c) 2010 Emmanuel Nicolau. See LICENSE for details.
|