enumify 0.0.1
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 +5 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +4 -0
- data/Rakefile +5 -0
- data/Readme.md +51 -0
- data/enumify.gemspec +25 -0
- data/lib/enumify.rb +3 -0
- data/lib/enumify/model.rb +49 -0
- data/lib/enumify/railtie.rb +9 -0
- data/lib/enumify/version.rb +3 -0
- data/spec/enumify/enum_spec.rb +104 -0
- data/spec/spec_helper.rb +2 -0
- metadata +120 -0
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Enumify
|
2
|
+
|
3
|
+
enumify adds an enum command to all ActiveRecord models which enables you to work with string attributes as if they were enums
|
4
|
+
|
5
|
+
## Installing
|
6
|
+
|
7
|
+
Just add the enumify gem to your GemFile
|
8
|
+
|
9
|
+
## How to use
|
10
|
+
|
11
|
+
Just call the enum function in any ActiveRecord object, the function accepts the field name as the first variable and the possible values as an array
|
12
|
+
|
13
|
+
class Event < ActiveRecord::Base
|
14
|
+
enum :status, [:available, :canceled, :completed]
|
15
|
+
end
|
16
|
+
|
17
|
+
After that you get several autogenerated commands to use with the enum
|
18
|
+
|
19
|
+
# Access through field name
|
20
|
+
|
21
|
+
event.status # returns the enum's current value as a symbol
|
22
|
+
event.status = :canceled # sets the enum's value to canceled (can also get a string)
|
23
|
+
|
24
|
+
|
25
|
+
# Shorthand methods, access through the possible values
|
26
|
+
|
27
|
+
event.available? # returns true if enum's current status is available
|
28
|
+
event.canceled! # changes the enum's value to canceled
|
29
|
+
|
30
|
+
# Get all the possible values
|
31
|
+
|
32
|
+
Event::STATUSES # returns all available status of the enum
|
33
|
+
|
34
|
+
## Callbacks
|
35
|
+
Another cool feature of enumify is the option to add a callback function that will be called each time the value of the field changes
|
36
|
+
This is cool to do stuff like log stuff or create behaviour on state changes
|
37
|
+
|
38
|
+
All you need to do is add a x_changed method in your class and the enumify will call it
|
39
|
+
|
40
|
+
class Event < ActiveRecord::Base
|
41
|
+
enum :status, [:available, :canceled, :completed]
|
42
|
+
|
43
|
+
def status_changed(old, new)
|
44
|
+
puts "status changed from #{old} to #{new}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
---
|
50
|
+
|
51
|
+
Copyright (c) 2011 Yonatan Bergman, released under the MIT license
|
data/enumify.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "enumify/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "enumify"
|
7
|
+
s.version = Enumify::VERSION
|
8
|
+
s.authors = ["yon"]
|
9
|
+
s.email = ["yonatanbergman@gmail.com"]
|
10
|
+
s.homepage = "http://github.com/yonbergman/enumify"
|
11
|
+
s.summary = %q{enumify adds an enum command to all ActiveRecord models which enables you to work with string attributes as if they were enums}
|
12
|
+
s.description = %q{enumify adds an enum command to all ActiveRecord models which enables you to work with string attributes as if they were enums}
|
13
|
+
|
14
|
+
s.rubyforge_project = "enumify"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n") - ["Gemfile.lock"]
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rake"
|
23
|
+
s.add_development_dependency "rspec"
|
24
|
+
s.add_development_dependency "supermodel"
|
25
|
+
end
|
data/lib/enumify.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Enumify
|
2
|
+
module Model
|
3
|
+
def enum(parameter, opts=[])
|
4
|
+
|
5
|
+
validates_inclusion_of parameter, :in => opts
|
6
|
+
|
7
|
+
const_set("#{parameter.to_s.pluralize.upcase}", opts)
|
8
|
+
|
9
|
+
define_method "#{parameter.to_s}" do
|
10
|
+
attr = read_attribute(parameter)
|
11
|
+
(attr.nil? || attr.empty?) ? nil : attr.to_sym
|
12
|
+
end
|
13
|
+
|
14
|
+
define_method "#{parameter.to_s}=" do |value|
|
15
|
+
send("_set_#{parameter.to_s}", value, false)
|
16
|
+
end
|
17
|
+
|
18
|
+
self.class_eval do
|
19
|
+
|
20
|
+
private
|
21
|
+
define_method "_set_#{parameter.to_s}" do |value, should_save|
|
22
|
+
|
23
|
+
value = value.to_sym
|
24
|
+
old = read_attribute(parameter) ? read_attribute(parameter).to_sym : nil
|
25
|
+
write_attribute(parameter, value.to_s)
|
26
|
+
save if should_save
|
27
|
+
send("#{parameter.to_s}_changed", old, value) if respond_to?("#{parameter.to_s}_changed", true) and old != value and !old.nil?
|
28
|
+
return value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.each do |opt|
|
33
|
+
raise "Collision in enum values method #{opt}" if respond_to?("#{opt.to_s}?") or respond_to?("#{opt.to_s}!") or respond_to?("#{opt.to_s}")
|
34
|
+
|
35
|
+
define_method "#{opt.to_s}?" do
|
36
|
+
send("#{parameter.to_s}") == opt
|
37
|
+
end
|
38
|
+
|
39
|
+
define_method "#{opt.to_s}!" do
|
40
|
+
send("_set_#{parameter.to_s}", opt, true)
|
41
|
+
end
|
42
|
+
|
43
|
+
scope opt.to_sym, where(parameter.to_sym => opt.to_s)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Model < SuperModel::Base
|
4
|
+
include ActiveModel::Validations
|
5
|
+
extend Enumify::Model
|
6
|
+
def self.scope(name,hash={}) self end
|
7
|
+
def self.where(hash={}) self end
|
8
|
+
|
9
|
+
enum :status, [:available, :canceled, :completed]
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
describe :Enumify do
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@obj = Model.new(:status => :available)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "short hand methods" do
|
20
|
+
describe "question mark (?)" do
|
21
|
+
it "should return true if value of enum equals a value" do
|
22
|
+
@obj.available?.should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return false if value of enum is different " do
|
26
|
+
@obj.canceled?.should be_false
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "exclemation mark (!)" do
|
32
|
+
it "should change the value of the enum to the methods value" do
|
33
|
+
@obj.canceled!
|
34
|
+
@obj.status.should == :canceled
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should have two shorthand methods for each possible value" do
|
39
|
+
Model::STATUSES.each do |val|
|
40
|
+
@obj.respond_to?("#{val}?").should be_true
|
41
|
+
@obj.respond_to?("#{val}!").should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "getting value" do
|
47
|
+
it "should always return the enums value as a symbol" do
|
48
|
+
@obj.status.should == :available
|
49
|
+
@obj.status = "canceled"
|
50
|
+
@obj.status.should == :canceled
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "setting value" do
|
56
|
+
it "should except values as symbol" do
|
57
|
+
@obj.status = :canceled
|
58
|
+
@obj.canceled?.should be_true
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should except values as string" do
|
62
|
+
@obj.status = "canceled"
|
63
|
+
@obj.canceled?.should be_true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "validations" do
|
68
|
+
it "should not except a value outside the given list" do
|
69
|
+
@obj = Model.new(:status => :available)
|
70
|
+
@obj.status = :foobar
|
71
|
+
@obj.should_not be_valid
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should except value in the list" do
|
75
|
+
@obj = Model.new(:status => :available)
|
76
|
+
@obj.status = :canceled
|
77
|
+
@obj.should be_valid
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "callbacks" do
|
82
|
+
it "should receive a callback on change of value" do
|
83
|
+
@obj.should_receive(:status_changed).with(:available,:canceled)
|
84
|
+
@obj.canceled!
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should not receive a callback on initial value" do
|
88
|
+
@obj = Model.new
|
89
|
+
@obj.should_not_receive(:status_changed).with(nil, :canceled)
|
90
|
+
@obj.canceled!
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should not receive a callback on value change to same" do
|
94
|
+
@obj.should_not_receive(:status_changed).with(:available, :available)
|
95
|
+
@obj.available!
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
it "class should have a CONST that holds all the available options of the enum" do
|
101
|
+
Model::STATUSES.should == [:available, :canceled, :completed]
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: enumify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- yon
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-12-20 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rake
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rspec
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: supermodel
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
type: :development
|
61
|
+
version_requirements: *id003
|
62
|
+
description: enumify adds an enum command to all ActiveRecord models which enables you to work with string attributes as if they were enums
|
63
|
+
email:
|
64
|
+
- yonatanbergman@gmail.com
|
65
|
+
executables: []
|
66
|
+
|
67
|
+
extensions: []
|
68
|
+
|
69
|
+
extra_rdoc_files: []
|
70
|
+
|
71
|
+
files:
|
72
|
+
- .gitignore
|
73
|
+
- .rspec
|
74
|
+
- CHANGELOG.md
|
75
|
+
- Gemfile
|
76
|
+
- Rakefile
|
77
|
+
- Readme.md
|
78
|
+
- enumify.gemspec
|
79
|
+
- lib/enumify.rb
|
80
|
+
- lib/enumify/model.rb
|
81
|
+
- lib/enumify/railtie.rb
|
82
|
+
- lib/enumify/version.rb
|
83
|
+
- spec/enumify/enum_spec.rb
|
84
|
+
- spec/spec_helper.rb
|
85
|
+
homepage: http://github.com/yonbergman/enumify
|
86
|
+
licenses: []
|
87
|
+
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
hash: 3
|
99
|
+
segments:
|
100
|
+
- 0
|
101
|
+
version: "0"
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
hash: 3
|
108
|
+
segments:
|
109
|
+
- 0
|
110
|
+
version: "0"
|
111
|
+
requirements: []
|
112
|
+
|
113
|
+
rubyforge_project: enumify
|
114
|
+
rubygems_version: 1.8.10
|
115
|
+
signing_key:
|
116
|
+
specification_version: 3
|
117
|
+
summary: enumify adds an enum command to all ActiveRecord models which enables you to work with string attributes as if they were enums
|
118
|
+
test_files:
|
119
|
+
- spec/enumify/enum_spec.rb
|
120
|
+
- spec/spec_helper.rb
|