ohm-contrib 1.0.rc1 → 1.0.0.rc2
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.markdown +0 -2
- data/lib/ohm/callbacks.rb +37 -139
- data/lib/ohm/contrib.rb +2 -1
- data/lib/ohm/datatypes.rb +1 -1
- data/lib/ohm/scope.rb +3 -4
- data/lib/ohm/softdelete.rb +12 -10
- data/lib/ohm/{timestamping.rb → timestamps.rb} +9 -17
- data/lib/ohm/versioned.rb +31 -0
- data/ohm-contrib.gemspec +3 -3
- data/test/helper.rb +9 -4
- data/test/plugin.rb +8 -10
- data/test/scope.rb +5 -21
- data/test/soft_delete.rb +3 -5
- data/test/{timestamping.rb → timestamp.rb} +2 -2
- data/test/versioned.rb +24 -0
- metadata +17 -17
- data/lib/ohm/plugin.rb +0 -54
- data/test/macro_callbacks.rb +0 -54
data/README.markdown
CHANGED
@@ -9,7 +9,6 @@ List of modules
|
|
9
9
|
1. [`Ohm::Boundaries`](http://cyx.github.com/ohm-contrib/doc/Ohm/Boundaries.html)
|
10
10
|
2. [`Ohm::Callbacks`](http://cyx.github.com/ohm-contrib/doc/Ohm/Callbacks.html)
|
11
11
|
3. [`Ohm::Timestamping`](http://cyx.github.com/ohm-contrib/doc/Ohm/Timestamping.html)
|
12
|
-
4. [`Ohm::ToHash`](http://cyx.github.com/ohm-contrib/doc/Ohm/ToHash.html)
|
13
12
|
5. [`Ohm::WebValidations`](http://cyx.github.com/ohm-contrib/doc/Ohm/WebValidations.html)
|
14
13
|
6. [`Ohm::NumberValidations`](http://cyx.github.com/ohm-contrib/doc/Ohm/NumberValidations.html)
|
15
14
|
7. [`Ohm::ExtraValidations`](http://cyx.github.com/ohm-contrib/doc/Ohm/ExtraValidations.html)
|
@@ -24,7 +23,6 @@ Example usage
|
|
24
23
|
|
25
24
|
class Post < Ohm::Model
|
26
25
|
include Ohm::Timestamping
|
27
|
-
include Ohm::ToHash
|
28
26
|
include Ohm::Boundaries
|
29
27
|
include Ohm::WebValidations
|
30
28
|
include Ohm::NumberValidations
|
data/lib/ohm/callbacks.rb
CHANGED
@@ -1,176 +1,74 @@
|
|
1
1
|
module Ohm
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# You can implement callbacks by overriding any of the following
|
5
|
-
# methods:
|
6
|
-
#
|
7
|
-
# - before_create
|
8
|
-
# - after_create
|
9
|
-
# - before_save
|
10
|
-
# - after_save
|
11
|
-
# - before_update
|
12
|
-
# - after_update
|
13
|
-
# - before_delete
|
14
|
-
# - after_delete
|
15
|
-
#
|
16
|
-
# If you prefer to do a class level declaration that is also possible.
|
17
|
-
#
|
18
|
-
# @example
|
2
|
+
# The following is an example usage of this plugin:
|
19
3
|
#
|
20
4
|
# class Post < Ohm::Model
|
21
5
|
# include Ohm::Callbacks
|
22
6
|
#
|
23
|
-
# before :create, :timestamp!
|
24
|
-
# before :save, :recalc_votes
|
25
|
-
#
|
26
|
-
# after :create, :post_to_twitter!
|
27
|
-
# after :save, :sync_ids
|
28
|
-
#
|
29
7
|
# protected
|
30
|
-
# def
|
8
|
+
# def before_create
|
31
9
|
# # sanitize the decimal values here
|
32
10
|
# end
|
33
11
|
#
|
34
|
-
# def
|
35
|
-
# # do timestamping code here
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
# def recalc_votes
|
12
|
+
# def before_save
|
39
13
|
# # do something here
|
40
14
|
# end
|
41
15
|
#
|
42
|
-
# def
|
16
|
+
# def after_create
|
43
17
|
# # do twitter posting here
|
44
18
|
# end
|
45
19
|
#
|
46
|
-
# def
|
20
|
+
# def after_save
|
47
21
|
# # do something with the ids
|
48
22
|
# end
|
49
23
|
# end
|
50
|
-
|
51
24
|
module Callbacks
|
52
|
-
def
|
53
|
-
|
54
|
-
|
25
|
+
def save!
|
26
|
+
is_new = new?
|
27
|
+
|
28
|
+
before_create if is_new
|
29
|
+
before_update if not is_new
|
30
|
+
before_save
|
55
31
|
|
56
|
-
|
57
|
-
# Use to add a before callback on `method`. Only symbols
|
58
|
-
# are allowed, no string eval, no block option also.
|
59
|
-
#
|
60
|
-
# @example
|
61
|
-
#
|
62
|
-
# class Post < Ohm::Model
|
63
|
-
# include Ohm::Callbacks
|
64
|
-
#
|
65
|
-
# before :create, :timestamp!
|
66
|
-
# before :save, :recalc_votes
|
67
|
-
#
|
68
|
-
# protected
|
69
|
-
# def timestamp!
|
70
|
-
# # do timestamping code here
|
71
|
-
# end
|
72
|
-
#
|
73
|
-
# def recalc_votes
|
74
|
-
# # do something here
|
75
|
-
# end
|
76
|
-
# end
|
77
|
-
#
|
78
|
-
# @param [Symbol] method the method type, e.g. `:create`, or `:save`
|
79
|
-
# @param [Symbol] callback the name of the method to execute
|
80
|
-
# @return [Array] the callback in an array if added e.g. [:timestamp]
|
81
|
-
# @return [nil] if the callback already exists
|
82
|
-
def before(method, callback)
|
83
|
-
unless callbacks[:before][method].include?(callback)
|
84
|
-
callbacks[:before][method] << callback
|
85
|
-
end
|
86
|
-
end
|
32
|
+
result = super
|
87
33
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
# @example
|
92
|
-
#
|
93
|
-
# class Post < Ohm::Model
|
94
|
-
# include Ohm::Callbacks
|
95
|
-
#
|
96
|
-
# after :create, :post_to_twitter!
|
97
|
-
# after :save, :sync_ids
|
98
|
-
#
|
99
|
-
# protected
|
100
|
-
# def post_to_twitter!
|
101
|
-
# # do twitter posting here
|
102
|
-
# end
|
103
|
-
#
|
104
|
-
# def sync_ids
|
105
|
-
# # do something with the ids
|
106
|
-
# end
|
107
|
-
# end
|
108
|
-
#
|
109
|
-
# @param [Symbol] method the method type, `:validate`, `:create`, or `:save`
|
110
|
-
# @param [Symbol] callback the name of the method to execute
|
111
|
-
# @return [Array] the callback in an array if added e.g. [:timestamp]
|
112
|
-
# @return [nil] if the callback already exists
|
113
|
-
def after(method, callback)
|
114
|
-
unless callbacks[:after][method].include?(callback)
|
115
|
-
callbacks[:after][method] << callback
|
116
|
-
end
|
117
|
-
end
|
34
|
+
after_create if is_new
|
35
|
+
after_update if not is_new
|
36
|
+
after_save
|
118
37
|
|
119
|
-
|
120
|
-
def callbacks
|
121
|
-
@callbacks ||= Hash.new { |h, k| h[k] = Hash.new { |h, k| h[k] = [] }}
|
122
|
-
end
|
38
|
+
return result
|
123
39
|
end
|
124
40
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
# executed.
|
130
|
-
def write
|
131
|
-
creating = @creating
|
41
|
+
def delete
|
42
|
+
before_delete
|
43
|
+
result = super
|
44
|
+
after_delete
|
132
45
|
|
133
|
-
|
134
|
-
|
135
|
-
execute_callback(:before, :save)
|
46
|
+
return result
|
47
|
+
end
|
136
48
|
|
137
|
-
|
49
|
+
protected
|
50
|
+
def before_save
|
51
|
+
end
|
138
52
|
|
139
|
-
|
140
|
-
execute_callback(:after, :update) unless creating
|
141
|
-
execute_callback(:after, :save)
|
53
|
+
def after_save
|
142
54
|
end
|
143
55
|
|
144
|
-
def
|
145
|
-
@creating = true
|
146
|
-
super.tap { @creating = false }
|
56
|
+
def before_create
|
147
57
|
end
|
148
58
|
|
149
|
-
def
|
150
|
-
execute_callback(:before, :delete)
|
151
|
-
super
|
152
|
-
execute_callback(:after, :delete)
|
59
|
+
def after_create
|
153
60
|
end
|
154
61
|
|
155
|
-
|
156
|
-
|
157
|
-
def after_validate() end
|
158
|
-
def before_save() end
|
159
|
-
def after_save() end
|
160
|
-
def before_create() end
|
161
|
-
def after_create() end
|
162
|
-
def before_update() end
|
163
|
-
def after_update() end
|
164
|
-
def before_delete() end
|
165
|
-
def after_delete() end
|
62
|
+
def before_update
|
63
|
+
end
|
166
64
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
65
|
+
def after_update
|
66
|
+
end
|
67
|
+
|
68
|
+
def before_delete
|
69
|
+
end
|
172
70
|
|
173
|
-
|
71
|
+
def after_delete
|
174
72
|
end
|
175
73
|
end
|
176
|
-
end
|
74
|
+
end
|
data/lib/ohm/contrib.rb
CHANGED
data/lib/ohm/datatypes.rb
CHANGED
@@ -7,7 +7,7 @@ module Ohm
|
|
7
7
|
module DataTypes
|
8
8
|
module Type
|
9
9
|
Integer = lambda { |x| x.to_i }
|
10
|
-
Decimal = lambda { |x|
|
10
|
+
Decimal = lambda { |x| BigDecimal(x.to_s) }
|
11
11
|
Float = lambda { |x| x.to_f }
|
12
12
|
Boolean = lambda { |x| !!x }
|
13
13
|
Time = lambda { |t| t && (t.kind_of?(::Time) ? t : ::Time.parse(t)) }
|
data/lib/ohm/scope.rb
CHANGED
@@ -22,9 +22,8 @@ module Ohm
|
|
22
22
|
extend model::DefinedScopes if defined?(model::DefinedScopes)
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
26
|
-
Ohm::Model::Set.send :include, OverloadedSet
|
27
25
|
end
|
28
26
|
|
29
|
-
|
30
|
-
|
27
|
+
Set.send :include, Scope::OverloadedSet
|
28
|
+
MultiSet.send :include, Scope::OverloadedSet
|
29
|
+
end
|
data/lib/ohm/softdelete.rb
CHANGED
@@ -43,17 +43,19 @@ module Ohm
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def delete
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
db.multi do
|
47
|
+
model.all.key.srem(id)
|
48
|
+
model.deleted.key.sadd(id)
|
49
|
+
set :deleted, DELETED_FLAG
|
50
|
+
end
|
50
51
|
end
|
51
52
|
|
52
53
|
def restore
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
db.multi do
|
55
|
+
model.all.key.sadd(id)
|
56
|
+
model.deleted.key.srem(id)
|
57
|
+
set :deleted, nil
|
58
|
+
end
|
57
59
|
end
|
58
60
|
|
59
61
|
def deleted?
|
@@ -62,7 +64,7 @@ module Ohm
|
|
62
64
|
|
63
65
|
module ClassMethods
|
64
66
|
def deleted
|
65
|
-
|
67
|
+
Set.new(key[:deleted], key, self)
|
66
68
|
end
|
67
69
|
|
68
70
|
def exists?(id)
|
@@ -70,4 +72,4 @@ module Ohm
|
|
70
72
|
end
|
71
73
|
end
|
72
74
|
end
|
73
|
-
end
|
75
|
+
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require_relative "callbacks"
|
2
1
|
require_relative "datatypes"
|
3
2
|
|
4
3
|
module Ohm
|
@@ -7,35 +6,28 @@ module Ohm
|
|
7
6
|
# @example
|
8
7
|
#
|
9
8
|
# class Post < Ohm::Model
|
10
|
-
# include Ohm::
|
9
|
+
# include Ohm::Timestamps
|
11
10
|
# end
|
12
11
|
#
|
13
12
|
# post = Post.create
|
14
|
-
# post.created_at.
|
13
|
+
# post.created_at.to_i == Time.now.utc.to_i
|
15
14
|
# # => true
|
16
15
|
#
|
17
16
|
# post = Post[post.id]
|
18
17
|
# post.save
|
19
|
-
# post.updated_at.
|
18
|
+
# post.updated_at.to_i == Time.now.utc.to_i
|
20
19
|
# # => true
|
21
|
-
module
|
20
|
+
module Timestamps
|
22
21
|
def self.included(model)
|
23
|
-
model.send :include, Callbacks
|
24
|
-
|
25
22
|
model.attribute :created_at, DataTypes::Type::Timestamp
|
26
23
|
model.attribute :updated_at, DataTypes::Type::Timestamp
|
27
|
-
|
28
|
-
model.before :create, :set_created_at
|
29
|
-
model.before :save, :set_updated_at
|
30
24
|
end
|
31
25
|
|
32
|
-
|
33
|
-
|
34
|
-
self.created_at ||= Time.now.utc.to_i
|
35
|
-
end
|
36
|
-
|
37
|
-
def set_updated_at
|
26
|
+
def save!
|
27
|
+
self.created_at = Time.now.utc.to_i if new?
|
38
28
|
self.updated_at = Time.now.utc.to_i
|
29
|
+
|
30
|
+
super
|
39
31
|
end
|
40
32
|
end
|
41
|
-
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Ohm
|
2
|
+
module Versioned
|
3
|
+
def self.included(model)
|
4
|
+
model.attribute :_version, lambda { |x| x.to_i }
|
5
|
+
end
|
6
|
+
|
7
|
+
def save!
|
8
|
+
super do |t|
|
9
|
+
t.read do |store|
|
10
|
+
current_version = key.hget(:_version).to_i
|
11
|
+
|
12
|
+
if current_version != _version
|
13
|
+
raise Ohm::VersionConflict.new(attributes)
|
14
|
+
end
|
15
|
+
|
16
|
+
self._version = current_version + 1
|
17
|
+
end
|
18
|
+
|
19
|
+
yield t if block_given?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class VersionConflict < StandardError
|
25
|
+
attr :attributes
|
26
|
+
|
27
|
+
def initialize(attributes)
|
28
|
+
@attributes = attributes
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/ohm-contrib.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "ohm-contrib"
|
3
|
-
s.version = "1.0.
|
3
|
+
s.version = "1.0.0.rc2"
|
4
4
|
s.summary = %{A collection of decoupled drop-in modules for Ohm.}
|
5
5
|
s.description = %{Includes a couple of core functions such as callbacks, timestamping, typecasting and lots of generic validation routines.}
|
6
6
|
s.author = "Cyril David"
|
@@ -22,9 +22,9 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.rubyforge_project = "ohm-contrib"
|
23
23
|
|
24
24
|
s.has_rdoc = false
|
25
|
-
s.add_dependency "ohm"
|
25
|
+
s.add_dependency "ohm", "1.0.0.rc1"
|
26
26
|
|
27
27
|
s.add_development_dependency "cutest"
|
28
28
|
s.add_development_dependency "redis"
|
29
29
|
s.add_development_dependency "override"
|
30
|
-
end
|
30
|
+
end
|
data/test/helper.rb
CHANGED
@@ -2,7 +2,13 @@ $:.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
|
|
2
2
|
|
3
3
|
require "cutest"
|
4
4
|
require "redis"
|
5
|
-
|
5
|
+
|
6
|
+
if ENV["SCRIPTED"]
|
7
|
+
require "ohm/scripted"
|
8
|
+
else
|
9
|
+
require "ohm"
|
10
|
+
end
|
11
|
+
|
6
12
|
require "ohm/contrib"
|
7
13
|
require "override"
|
8
14
|
|
@@ -12,10 +18,10 @@ NOW = Time.utc(2010, 5, 12)
|
|
12
18
|
|
13
19
|
include Override
|
14
20
|
|
15
|
-
prepare
|
21
|
+
prepare do
|
16
22
|
Ohm.flush
|
17
23
|
override(Time, :now => NOW)
|
18
|
-
|
24
|
+
end
|
19
25
|
|
20
26
|
def assert_nothing_raised(*exceptions)
|
21
27
|
begin
|
@@ -24,4 +30,3 @@ def assert_nothing_raised(*exceptions)
|
|
24
30
|
flunk(caller[1])
|
25
31
|
end
|
26
32
|
end
|
27
|
-
|
data/test/plugin.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative "helper"
|
4
4
|
|
5
5
|
class Comment < Ohm::Model
|
6
|
-
include Ohm::
|
6
|
+
include Ohm::Timestamps
|
7
7
|
end
|
8
8
|
|
9
9
|
test "timestamps are added during creation" do
|
@@ -26,17 +26,15 @@ class Article < Ohm::Model
|
|
26
26
|
include Ohm::Callbacks
|
27
27
|
|
28
28
|
attribute :title
|
29
|
-
|
30
|
-
list :comments, Comment
|
31
|
-
after :save, :append_comment
|
29
|
+
set :comments, Comment
|
32
30
|
|
33
31
|
private
|
34
32
|
def before_save
|
35
33
|
self.title = title.gsub("<br>", " ")
|
36
34
|
end
|
37
35
|
|
38
|
-
def
|
39
|
-
comments.
|
36
|
+
def after_save
|
37
|
+
comments.key.sadd(Comment.create.id)
|
40
38
|
end
|
41
39
|
end
|
42
40
|
|
@@ -135,7 +133,7 @@ class Product < Ohm::Model
|
|
135
133
|
attribute :published, Type::Boolean
|
136
134
|
end
|
137
135
|
|
138
|
-
test "
|
136
|
+
test "datatypes" do
|
139
137
|
p = Product.new(stock: "1")
|
140
138
|
|
141
139
|
assert_equal 1, p.stock
|
@@ -155,6 +153,7 @@ test "typecast" do
|
|
155
153
|
assert_equal time, p.bought_at
|
156
154
|
|
157
155
|
p = Product.new(date_released: Date.today)
|
156
|
+
|
158
157
|
assert p.date_released.kind_of?(Date)
|
159
158
|
|
160
159
|
p = Product.new(date_released: "2011-11-22")
|
@@ -163,13 +162,12 @@ test "typecast" do
|
|
163
162
|
p.save
|
164
163
|
|
165
164
|
p = Product[p.id]
|
166
|
-
assert_equal Date.
|
165
|
+
assert_equal Date.new(2011, 11, 22), p.date_released
|
167
166
|
|
168
167
|
sizes = { "XS" => 1, "S" => 2, "L" => 3 }
|
169
168
|
|
170
169
|
p = Product.new(sizes: sizes)
|
171
170
|
assert p.sizes.kind_of?(Hash)
|
172
|
-
|
173
171
|
p.save
|
174
172
|
|
175
173
|
p = Product[p.id]
|
@@ -209,4 +207,4 @@ test "typecast" do
|
|
209
207
|
|
210
208
|
p = Product[p.id]
|
211
209
|
assert_equal true, p.published
|
212
|
-
end
|
210
|
+
end
|
data/test/scope.rb
CHANGED
@@ -3,11 +3,7 @@
|
|
3
3
|
require_relative "helper"
|
4
4
|
|
5
5
|
class Post < Ohm::Model
|
6
|
-
set :comments, Comment
|
7
|
-
end
|
8
|
-
|
9
|
-
class Video < Ohm::Model
|
10
|
-
list :comments, Comment
|
6
|
+
set :comments, :Comment
|
11
7
|
end
|
12
8
|
|
13
9
|
module Finders
|
@@ -38,18 +34,18 @@ end
|
|
38
34
|
test "allows custom methods for the defined scopes" do
|
39
35
|
post = Post.create
|
40
36
|
comment = Comment.create(:status => "approved")
|
41
|
-
post.comments
|
37
|
+
post.comments.key.sadd(comment.id)
|
42
38
|
|
43
|
-
assert post.comments.approved.is_a?(Ohm::
|
39
|
+
assert post.comments.approved.is_a?(Ohm::MultiSet)
|
44
40
|
assert post.comments.approved.include?(comment)
|
45
41
|
end
|
46
42
|
|
47
43
|
test "allows custom methods to be included from a module" do
|
48
44
|
post = Post.create
|
49
45
|
comment = Comment.create(:status => "rejected")
|
50
|
-
post.comments
|
46
|
+
post.comments.key.sadd(comment.id)
|
51
47
|
|
52
|
-
assert post.comments.rejected.is_a?(Ohm::
|
48
|
+
assert post.comments.rejected.is_a?(Ohm::MultiSet)
|
53
49
|
assert post.comments.rejected.include?(comment)
|
54
50
|
end
|
55
51
|
|
@@ -61,15 +57,3 @@ test "works with the main Comment.all collection as well" do
|
|
61
57
|
assert Comment.all.approved.include?(approved)
|
62
58
|
assert Comment.all.rejected.include?(rejected)
|
63
59
|
end
|
64
|
-
|
65
|
-
test "isolated from List" do
|
66
|
-
video = Video.create
|
67
|
-
|
68
|
-
assert_raise NoMethodError do
|
69
|
-
video.comments.approved
|
70
|
-
end
|
71
|
-
|
72
|
-
assert_raise NoMethodError do
|
73
|
-
video.comments.rejected
|
74
|
-
end
|
75
|
-
end
|
data/test/soft_delete.rb
CHANGED
@@ -40,18 +40,16 @@ test "find does not exclude deleted records" do
|
|
40
40
|
person.delete
|
41
41
|
|
42
42
|
assert Person.find(:name => "matz").include?(person)
|
43
|
-
assert Person.all.find(:name => "matz").include?(person)
|
44
43
|
end
|
45
44
|
|
46
|
-
test "find with many criteria
|
45
|
+
test "find with many criteria doesn't exclude deleted records" do
|
47
46
|
person = Person.create(:name => "matz", :age => 38)
|
48
47
|
|
49
48
|
assert Person.find(:name => "matz", :age => 38).first == person
|
50
49
|
|
51
50
|
person.delete
|
52
51
|
|
53
|
-
assert Person.find(:name => "matz", :age => 38).
|
54
|
-
assert Person.all.find(:name => "matz", :age => 38).empty?
|
52
|
+
assert Person.find(:name => "matz", :age => 38).include?(person)
|
55
53
|
end
|
56
54
|
|
57
55
|
test "exists? returns true for deleted records" do
|
@@ -79,4 +77,4 @@ test "restoring" do
|
|
79
77
|
|
80
78
|
person.restore
|
81
79
|
assert Person.all.include?(person)
|
82
|
-
end
|
80
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require File.expand_path("./helper", File.dirname(__FILE__))
|
4
4
|
|
5
5
|
class Person < Ohm::Model
|
6
|
-
include Ohm::
|
6
|
+
include Ohm::Timestamps
|
7
7
|
end
|
8
8
|
|
9
9
|
test "a new? record" do
|
@@ -28,4 +28,4 @@ test "on update" do
|
|
28
28
|
|
29
29
|
assert NOW == person.created_at
|
30
30
|
assert Time.utc(2010, 5, 13) == person.updated_at
|
31
|
-
end
|
31
|
+
end
|
data/test/versioned.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative "helper"
|
2
|
+
|
3
|
+
class Article < Ohm::Model
|
4
|
+
include Ohm::Versioned
|
5
|
+
|
6
|
+
attribute :title
|
7
|
+
attribute :content
|
8
|
+
end
|
9
|
+
|
10
|
+
test do
|
11
|
+
a1 = Article.create(title: "Foo Bar", content: "Lorem ipsum")
|
12
|
+
a2 = Article[a1.id]
|
13
|
+
|
14
|
+
a1.update({})
|
15
|
+
|
16
|
+
begin
|
17
|
+
a2.update(title: "Bar Baz")
|
18
|
+
rescue Ohm::VersionConflict => ex
|
19
|
+
end
|
20
|
+
|
21
|
+
expected = { title: "Bar Baz", _version: "1", content: "Lorem ipsum" }
|
22
|
+
|
23
|
+
assert_equal expected, ex.attributes
|
24
|
+
end
|
metadata
CHANGED
@@ -1,30 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ohm-contrib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0.rc2
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Cyril David
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-04-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ohm
|
16
|
-
requirement: &
|
16
|
+
requirement: &70287509765700 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - =
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 1.0.0.rc1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70287509765700
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: cutest
|
27
|
-
requirement: &
|
27
|
+
requirement: &70287509764720 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70287509764720
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: redis
|
38
|
-
requirement: &
|
38
|
+
requirement: &70287509763280 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70287509763280
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: override
|
49
|
-
requirement: &
|
49
|
+
requirement: &70287509762640 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70287509762640
|
58
58
|
description: Includes a couple of core functions such as callbacks, timestamping,
|
59
59
|
typecasting and lots of generic validation routines.
|
60
60
|
email: cyx.ucron@gmail.com
|
@@ -69,20 +69,20 @@ files:
|
|
69
69
|
- lib/ohm/contrib.rb
|
70
70
|
- lib/ohm/datatypes.rb
|
71
71
|
- lib/ohm/locking.rb
|
72
|
-
- lib/ohm/plugin.rb
|
73
72
|
- lib/ohm/scope.rb
|
74
73
|
- lib/ohm/slug.rb
|
75
74
|
- lib/ohm/softdelete.rb
|
76
|
-
- lib/ohm/
|
75
|
+
- lib/ohm/timestamps.rb
|
76
|
+
- lib/ohm/versioned.rb
|
77
77
|
- ohm-contrib.gemspec
|
78
78
|
- test/helper.rb
|
79
79
|
- test/instance_callbacks.rb
|
80
|
-
- test/macro_callbacks.rb
|
81
80
|
- test/plugin.rb
|
82
81
|
- test/scope.rb
|
83
82
|
- test/slug.rb
|
84
83
|
- test/soft_delete.rb
|
85
|
-
- test/
|
84
|
+
- test/timestamp.rb
|
85
|
+
- test/versioned.rb
|
86
86
|
homepage: http://github.com/cyx/ohm-contrib
|
87
87
|
licenses: []
|
88
88
|
post_install_message:
|
data/lib/ohm/plugin.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
module Ohm
|
2
|
-
module Plugin
|
3
|
-
def plugin(name)
|
4
|
-
mixin = Plugin[name]
|
5
|
-
|
6
|
-
include mixin
|
7
|
-
extend mixin::ClassMethods if mixin.const_defined?(:ClassMethods, false)
|
8
|
-
|
9
|
-
mixin.setup(self) if mixin.respond_to?(:setup)
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.[](plugin)
|
13
|
-
case plugin
|
14
|
-
when Module
|
15
|
-
plugin
|
16
|
-
when Symbol
|
17
|
-
name, path = Plugin.registry[plugin]
|
18
|
-
|
19
|
-
raise Unknown.new(plugin) if name.nil?
|
20
|
-
|
21
|
-
require path
|
22
|
-
Ohm.const_get(name, false)
|
23
|
-
else
|
24
|
-
raise Unknown.new(plugin)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.register(name, name_and_path)
|
29
|
-
registry[name] = name_and_path
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.registry
|
33
|
-
@registry ||= {
|
34
|
-
:callbacks => [:Callbacks, "ohm/contrib/callbacks"],
|
35
|
-
:datatypes => [:DataTypes, "ohm/contrib/data_types"],
|
36
|
-
:locking => [:Locking, "ohm/contrib/locking"],
|
37
|
-
:scope => [:Scope, "ohm/contrib/scope"],
|
38
|
-
:slug => [:Slug, "ohm/contrib/slug"],
|
39
|
-
:softdelete => [:SoftDelete, "ohm/contrib/soft_delete"],
|
40
|
-
:timestamping => [:Timestamping, "ohm/contrib/timestamping"]
|
41
|
-
}
|
42
|
-
end
|
43
|
-
|
44
|
-
class Unknown < StandardError
|
45
|
-
def initialize(plugin)
|
46
|
-
@plugin = plugin
|
47
|
-
end
|
48
|
-
|
49
|
-
def message
|
50
|
-
"Unknown plugin: #{@plugin}"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
data/test/macro_callbacks.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("./helper", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
class Post < Ohm::Model
|
6
|
-
include Ohm::Callbacks
|
7
|
-
|
8
|
-
attribute :body
|
9
|
-
|
10
|
-
before :create, :do_before_create
|
11
|
-
after :create, :do_after_create
|
12
|
-
|
13
|
-
before :save, :do_before_save
|
14
|
-
after :save, :do_after_save
|
15
|
-
|
16
|
-
before :delete, :do_before_delete
|
17
|
-
after :delete, :do_after_delete
|
18
|
-
|
19
|
-
before :update, :do_before_update
|
20
|
-
after :update, :do_after_update
|
21
|
-
|
22
|
-
def validate
|
23
|
-
assert_present :body
|
24
|
-
end
|
25
|
-
|
26
|
-
def did?(action)
|
27
|
-
instance_variable_get("@#{ action }")
|
28
|
-
end
|
29
|
-
|
30
|
-
def count(action)
|
31
|
-
instance_variable_get("@#{ action }")
|
32
|
-
end
|
33
|
-
|
34
|
-
protected
|
35
|
-
def do_before_create() incr(:do_before_create) end
|
36
|
-
def do_after_create() incr(:do_after_create) end
|
37
|
-
def do_before_save() incr(:do_before_save) end
|
38
|
-
def do_after_save() incr(:do_after_save) end
|
39
|
-
def do_before_update() incr(:do_before_update) end
|
40
|
-
def do_after_update() incr(:do_after_update) end
|
41
|
-
def do_before_delete() incr(:do_before_delete) end
|
42
|
-
def do_after_delete() incr(:do_after_delete) end
|
43
|
-
|
44
|
-
|
45
|
-
def incr(action)
|
46
|
-
val = instance_variable_get("@#{ action }")
|
47
|
-
val ||= 0
|
48
|
-
val += 1
|
49
|
-
|
50
|
-
instance_variable_set("@#{ action }", val)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
load File.expand_path('lint/callbacks.rb', File.dirname(__FILE__))
|