status-manager 0.1.3 → 0.1.4
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/README.md +40 -11
- data/lib/status-manager.rb +22 -4
- data/lib/status-manager/{status-group-manager.rb → status_group_manager.rb} +5 -1
- data/lib/status-manager/status_update_callback.rb +31 -0
- data/lib/status-manager/status_validation.rb +5 -0
- data/lib/status-manager/version.rb +1 -1
- data/status-manager-0.1.3.gem +0 -0
- data/status-manager.gemspec +3 -2
- data/status_manager_test.sqlite3 +0 -0
- data/test/models/product.rb +13 -2
- data/test/status-manager_test.rb +6 -22
- metadata +11 -4
data/README.md
CHANGED
@@ -14,34 +14,63 @@ gem 'status-manager'
|
|
14
14
|
|
15
15
|
### Example
|
16
16
|
|
17
|
+
#### Define
|
17
18
|
```ruby
|
18
19
|
class Product < ActiveRecord::Base
|
19
|
-
attr_accessible :title, :
|
20
|
+
attr_accessible :title, :sale_status
|
20
21
|
|
21
22
|
# attr_as_status :status_attribute in model, {:status_value => 'status_value that is saved in database'}
|
22
|
-
attr_as_status :
|
23
|
-
status_group :
|
23
|
+
attr_as_status :sale_status, :onsale => 'onsale', :reject => 'reject', :pending => 'pending', :soldout => 'soldout'
|
24
|
+
status_group :sale_status, :close => [:reject, :pending], :open => [:onsale, :soldout]
|
24
25
|
|
25
26
|
end
|
26
27
|
```
|
27
28
|
|
29
|
+
### Queries
|
28
30
|
```ruby
|
29
31
|
## select
|
30
|
-
|
31
|
-
@closed_product = Product.my_status_close.first
|
32
|
+
Product.sale_statuses #=> {:onsale => 'onsale', :reject => 'reject', :pending => 'pending', :soldout => 'soldout'}
|
32
33
|
|
33
|
-
@onsale_product
|
34
|
+
@onsale_product = Product.sale_status_onsale.first
|
35
|
+
@closed_product = Product.sale_status_close.first
|
36
|
+
|
37
|
+
@onsale_product.sale_status_onsale? #=> true
|
34
38
|
#or
|
35
|
-
@closed_product.
|
39
|
+
@closed_product.sale_status?(:close) #=> true
|
36
40
|
|
37
41
|
## update just attribute value
|
38
|
-
@closed_product.
|
42
|
+
@closed_product.sale_status_to(:onsale)
|
39
43
|
#or
|
40
|
-
@closed_product.
|
44
|
+
@closed_product.sale_Status_to_onsale
|
41
45
|
|
42
46
|
## update with database
|
43
|
-
@closed_product.
|
47
|
+
@closed_product.update_sale_status_to(:onsale)
|
44
48
|
#or
|
45
|
-
@closed_product.
|
49
|
+
@closed_product.update_sale_status_to_onsale
|
50
|
+
```
|
46
51
|
|
52
|
+
### Callback
|
53
|
+
``` ruby
|
54
|
+
class Product < ActiveRecord::Base
|
55
|
+
attr_accessible :title, :sale_status
|
56
|
+
|
57
|
+
# attr_as_status :status_attribute in model, {:status_value => 'status_value that is saved in database'}
|
58
|
+
attr_as_status :sale_status, :onsale => 'onsale', :reject => 'reject', :pending => 'pending', :soldout => 'soldout'
|
59
|
+
status_group :sale_status, :close => [:reject, :pending], :open => [:onsale, :soldout]
|
60
|
+
|
61
|
+
before_status_update :sale_status, :onsale => :close do |product|
|
62
|
+
puts "#{product.title} is closed"
|
63
|
+
end
|
64
|
+
|
65
|
+
after_status_update :sale_status, :close => :onsale do |product|
|
66
|
+
puts "closed #{product.title} is opened"
|
67
|
+
# do something after update
|
68
|
+
end
|
69
|
+
|
70
|
+
after_status_update :sale_status, :reject do |prdocut|
|
71
|
+
puts "#{product.title} is rejected"
|
72
|
+
# do something after update
|
73
|
+
end
|
74
|
+
end
|
47
75
|
|
76
|
+
```
|
data/lib/status-manager.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
require 'status-manager/
|
1
|
+
require 'status-manager/status_group_manager'
|
2
|
+
require 'status-manager/status_update_callback'
|
3
|
+
require 'status-manager/status_validation'
|
4
|
+
require 'active_support/inflector'
|
2
5
|
|
3
6
|
module StatusManager
|
4
7
|
|
5
8
|
def self.included(base)
|
6
|
-
base.extend
|
9
|
+
base.extend ClassMethods
|
10
|
+
base.extend StatusManager::StatusGroupManager
|
11
|
+
base.extend StatusManager::StatusUpdateCallback
|
12
|
+
base.extend StatusManager::StatusValidation
|
7
13
|
end
|
8
14
|
|
9
15
|
module ClassMethods
|
@@ -19,6 +25,10 @@ module StatusManager
|
|
19
25
|
self.send("#{status_title}") == value
|
20
26
|
end
|
21
27
|
|
28
|
+
define_method "#{status_title}_was_#{key}?" do
|
29
|
+
self.send("#{status_title}_was") == value
|
30
|
+
end
|
31
|
+
|
22
32
|
#update status
|
23
33
|
define_method "update_#{status_title}_to_#{key}" do
|
24
34
|
self.update_attributes("#{status_title}" => "#{value}")
|
@@ -34,6 +44,10 @@ module StatusManager
|
|
34
44
|
self.send("#{status_title}_#{status}?")
|
35
45
|
end
|
36
46
|
|
47
|
+
define_method "#{status_title}_was?" do |status|
|
48
|
+
self.send("#{status_title}_was_#{status}?")
|
49
|
+
end
|
50
|
+
|
37
51
|
#status setter (do not override attr_accessible)
|
38
52
|
define_method "#{status_title}_to" do |next_status|
|
39
53
|
status_value = self.class.manager_status_list[status_title][next_status]
|
@@ -41,11 +55,14 @@ module StatusManager
|
|
41
55
|
end
|
42
56
|
|
43
57
|
# update status
|
44
|
-
define_method "update_#{status_title}" do |next_status|
|
58
|
+
define_method "update_#{status_title}_to" do |next_status|
|
45
59
|
self.update_attributes(status_title.to_sym => self.class.manager_status_list[status_title][next_status])
|
46
60
|
end
|
47
61
|
|
48
|
-
|
62
|
+
#get status list
|
63
|
+
define_singleton_method "#{status_title.to_s.pluralize}" do
|
64
|
+
self.manager_status_list[status_title.to_sym]
|
65
|
+
end
|
49
66
|
end
|
50
67
|
|
51
68
|
def manager_status_list
|
@@ -57,6 +74,7 @@ module StatusManager
|
|
57
74
|
end
|
58
75
|
status_list
|
59
76
|
end
|
77
|
+
|
60
78
|
end
|
61
79
|
end
|
62
80
|
|
@@ -14,7 +14,11 @@ module StatusManager
|
|
14
14
|
|
15
15
|
# status check method
|
16
16
|
define_method "#{status_title}_#{group_status_title}?" do
|
17
|
-
group_status_values.include? self.send(status_title
|
17
|
+
group_status_values.include? self.send(status_title)
|
18
|
+
end
|
19
|
+
|
20
|
+
define_method "#{status_title}_was_#{group_status_title}?" do
|
21
|
+
group_status_values.include? self.send("#{status_title}_was")
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module StatusManager
|
2
|
+
module StatusUpdateCallback
|
3
|
+
def after_status_update(status_title, status_way, &block)
|
4
|
+
self.after_update do |obj|
|
5
|
+
self.class.send(:status_update_callback, obj, status_title, status_way, &block)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def before_status_update(status_title, status_way, &block)
|
10
|
+
self.before_update do |obj|
|
11
|
+
self.class.send(:status_update_callback, obj, status_title, status_way, &block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def status_update_callback(obj, status_title, status_way, &block)
|
16
|
+
if obj.send("#{status_title}_changed?")
|
17
|
+
if status_way.class == Hash
|
18
|
+
prev_status = status_way.first[0]
|
19
|
+
next_status = status_way.first[1]
|
20
|
+
if obj.send("#{status_title}_was_#{prev_status}?") && obj.send("#{status_title}_#{next_status}?")
|
21
|
+
block.call(obj)
|
22
|
+
end
|
23
|
+
elsif status_way.class == Symbol
|
24
|
+
if obj.send("#{status_title}_#{status_way}?")
|
25
|
+
block.call(obj)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
Binary file
|
data/status-manager.gemspec
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'status-manager'
|
3
|
-
s.version = '0.1.
|
4
|
-
s.date = '2013-08-
|
3
|
+
s.version = '0.1.4'
|
4
|
+
s.date = '2013-08-17'
|
5
5
|
s.summary = "ActiveRecord Model Status Manager"
|
6
6
|
s.description = "ActiveRecord Model Status Manager"
|
7
7
|
s.authors = ["Keepcosmos"]
|
8
8
|
s.email = 'keepcosmos@gmail.com'
|
9
|
+
s.licenses = 'MIT'
|
9
10
|
|
10
11
|
s.files = `git ls-files`.split("\n")
|
11
12
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/status_manager_test.sqlite3
CHANGED
Binary file
|
data/test/models/product.rb
CHANGED
@@ -4,6 +4,17 @@ class Product < ActiveRecord::Base
|
|
4
4
|
# acts_as_status :status_attribute in model, {:status_value => 'status_value that is saved in database'}
|
5
5
|
attr_as_status :sale_status, :onsale => 'onsale', :reject => 'reject', :pending => 'pending', :soldout => 'soldout'
|
6
6
|
status_group :sale_status, :close => [:reject, :pending], :open => [:onsale, :soldout]
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
before_status_update :sale_status, :close => :onsale do |product|
|
9
|
+
puts "open #{product.title}"
|
10
|
+
end
|
11
|
+
|
12
|
+
after_status_update :sale_status, :pending => :onsale do |product|
|
13
|
+
puts "release #{product.title}"
|
14
|
+
end
|
15
|
+
|
16
|
+
after_status_update :sale_status, :onsale do |product|
|
17
|
+
puts "onsale #{product.title}"
|
18
|
+
end
|
19
|
+
|
9
20
|
end
|
data/test/status-manager_test.rb
CHANGED
@@ -3,6 +3,11 @@ require 'models/product'
|
|
3
3
|
|
4
4
|
class StatusManagerTest < Test::Unit::TestCase
|
5
5
|
|
6
|
+
def test_status_chagne
|
7
|
+
product = Product.sale_status_pending.first
|
8
|
+
product.update_sale_status_to_onsale
|
9
|
+
end
|
10
|
+
|
6
11
|
def test_current_status
|
7
12
|
products = Product.sale_status_onsale
|
8
13
|
products.each do |product|
|
@@ -24,7 +29,7 @@ class StatusManagerTest < Test::Unit::TestCase
|
|
24
29
|
assert product.sale_status_reject?
|
25
30
|
assert product.sale_status? :reject
|
26
31
|
|
27
|
-
product.
|
32
|
+
product.update_sale_status_to :soldout
|
28
33
|
assert Product.find(product.id).sale_status_soldout?
|
29
34
|
|
30
35
|
product.update_sale_status_to_onsale
|
@@ -45,26 +50,5 @@ class StatusManagerTest < Test::Unit::TestCase
|
|
45
50
|
end
|
46
51
|
end
|
47
52
|
|
48
|
-
# def test_current_status
|
49
|
-
# product = Product.first
|
50
|
-
# assert_equal true, product.sale_status_onsale?
|
51
|
-
# end
|
52
|
-
|
53
|
-
# def test_status_scope
|
54
|
-
# products = Product.sale_status_reject
|
55
|
-
# products.each do |product|
|
56
|
-
# assert product.sale_status_reject?, "#{product.id} is not rejected product"
|
57
|
-
# end
|
58
|
-
# end
|
59
|
-
|
60
|
-
# def test_status_update
|
61
|
-
# product = Product.sale_status_reject.first
|
62
|
-
# product.sale_status_to(:soldout)
|
63
|
-
# assert product.sale_status_soldout?
|
64
|
-
# assert product.update_status_to_onsale
|
65
|
-
# assert product.sale_status_onsale?
|
66
|
-
# product.update_status(:soldout)
|
67
|
-
# assert product.sale_status_soldout?
|
68
|
-
# end
|
69
53
|
|
70
54
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: status-manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-17 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ActiveRecord Model Status Manager
|
15
15
|
email: keepcosmos@gmail.com
|
@@ -24,9 +24,15 @@ files:
|
|
24
24
|
- !binary |-
|
25
25
|
bGliL3N0YXR1cy1tYW5hZ2VyLnJi
|
26
26
|
- !binary |-
|
27
|
-
|
27
|
+
bGliL3N0YXR1cy1tYW5hZ2VyL3N0YXR1c19ncm91cF9tYW5hZ2VyLnJi
|
28
|
+
- !binary |-
|
29
|
+
bGliL3N0YXR1cy1tYW5hZ2VyL3N0YXR1c191cGRhdGVfY2FsbGJhY2sucmI=
|
30
|
+
- !binary |-
|
31
|
+
bGliL3N0YXR1cy1tYW5hZ2VyL3N0YXR1c192YWxpZGF0aW9uLnJi
|
28
32
|
- !binary |-
|
29
33
|
bGliL3N0YXR1cy1tYW5hZ2VyL3ZlcnNpb24ucmI=
|
34
|
+
- !binary |-
|
35
|
+
c3RhdHVzLW1hbmFnZXItMC4xLjMuZ2Vt
|
30
36
|
- !binary |-
|
31
37
|
c3RhdHVzLW1hbmFnZXIuZ2Vtc3BlYw==
|
32
38
|
- !binary |-
|
@@ -44,7 +50,8 @@ files:
|
|
44
50
|
- !binary |-
|
45
51
|
dGVzdC90ZXN0X2luaXRpYWxpemVyLnJi
|
46
52
|
homepage: https://github.com/keepcosmos/status-manager
|
47
|
-
licenses:
|
53
|
+
licenses:
|
54
|
+
- MIT
|
48
55
|
post_install_message:
|
49
56
|
rdoc_options: []
|
50
57
|
require_paths:
|