mongo_mapper_acts_as_versioned 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -3
- data/lib/acts_as_versioned.rb +53 -43
- data/spec/acts_as_versioned_spec.rb +61 -4
- metadata +2 -3
- data/lib/acts_as_versioned/version.rb +0 -7
data/README.md
CHANGED
@@ -43,11 +43,13 @@ Default ignored keys are:
|
|
43
43
|
* "creator\_id"
|
44
44
|
* "updater\_id"
|
45
45
|
* "version"
|
46
|
-
*
|
46
|
+
* "\_type"
|
47
|
+
* "\_versioned\_type"
|
48
|
+
* versioned\_foreign\_key
|
47
49
|
|
48
50
|
### Ignoring additional keys
|
49
51
|
|
50
|
-
Simply add `self.
|
52
|
+
Simply add `self.non_versioned_keys << 'new_skipped_key'` somewhere in your model.
|
51
53
|
|
52
54
|
## Tested with
|
53
55
|
|
@@ -58,7 +60,6 @@ Simply add `self.skipped_keys << 'new_skipped_key'` somewhere in your model.
|
|
58
60
|
|
59
61
|
* Add loads more options
|
60
62
|
* Properly document those options
|
61
|
-
* Support SCI
|
62
63
|
|
63
64
|
## Bundler note
|
64
65
|
|
data/lib/acts_as_versioned.rb
CHANGED
@@ -1,27 +1,48 @@
|
|
1
1
|
module MongoMapper
|
2
2
|
module Acts
|
3
3
|
module Versioned
|
4
|
+
VERSION = '0.0.4'
|
4
5
|
CALLBACKS = [:set_new_version, :save_version, :save_version?]
|
5
6
|
|
6
7
|
def self.configure(model)
|
7
8
|
model.class_eval do
|
8
|
-
|
9
|
+
cattr_accessor :versioned_class_name, :versioned_foreign_key,
|
10
|
+
:versioned_collection_name, :non_versioned_keys
|
11
|
+
|
12
|
+
self.versioned_class_name = :Version
|
13
|
+
self.versioned_foreign_key = self.to_s.foreign_key
|
14
|
+
self.versioned_collection_name = "#{collection_name.singularize}_versions"
|
15
|
+
self.non_versioned_keys = [
|
16
|
+
'_id', 'created_at', 'updated_at', 'creator_id',
|
17
|
+
'updater_id', 'version', versioned_foreign_key,
|
18
|
+
'_type', '_version_type'
|
19
|
+
]
|
20
|
+
|
21
|
+
const_set(versioned_class_name, Class.new).class_eval do
|
9
22
|
include MongoMapper::Document
|
10
23
|
|
24
|
+
class << self
|
25
|
+
delegate :versioned_foreign_key, :to => :original_class
|
26
|
+
end
|
27
|
+
|
11
28
|
key :version, Integer
|
12
29
|
key :changed_attributes, Hash
|
13
30
|
|
31
|
+
if type_key = keys['_type']
|
32
|
+
key :_version_type, type_key.type, type_key.options
|
33
|
+
end
|
34
|
+
|
14
35
|
def self.before(version)
|
15
36
|
where(
|
16
|
-
|
17
|
-
:version.lt
|
37
|
+
versioned_foreign_key => version[versioned_foreign_key],
|
38
|
+
:version.lt => version.version
|
18
39
|
).sort(:version.desc).first
|
19
40
|
end
|
20
41
|
|
21
42
|
def self.after(version)
|
22
43
|
where(
|
23
|
-
|
24
|
-
:version.gt
|
44
|
+
versioned_foreign_key => version[versioned_foreign_key],
|
45
|
+
:version.gt => version.version
|
25
46
|
).sort(:version.asc).first
|
26
47
|
end
|
27
48
|
|
@@ -32,37 +53,33 @@ module MongoMapper
|
|
32
53
|
def next
|
33
54
|
self.class.after(self)
|
34
55
|
end
|
35
|
-
|
36
|
-
def self.super_foreign_key
|
37
|
-
original_class.to_s.foreign_key
|
38
|
-
end
|
39
|
-
|
40
|
-
class << self
|
41
|
-
protected :super_foreign_key
|
42
|
-
end
|
43
56
|
end
|
44
57
|
|
45
58
|
versioned_class.cattr_accessor :original_class
|
46
59
|
versioned_class.original_class = self
|
47
|
-
versioned_class.set_collection_name
|
60
|
+
versioned_class.set_collection_name versioned_collection_name
|
48
61
|
versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
|
49
|
-
|
50
|
-
|
51
|
-
end
|
62
|
+
:class_name => self.to_s,
|
63
|
+
:foreign_key => versioned_foreign_key
|
52
64
|
|
53
|
-
|
54
|
-
model.many :versions, :class_name => "#{model}::Version",
|
55
|
-
:foreign_key => model.to_s.foreign_key, :dependent => :destroy do
|
56
|
-
def earliest
|
57
|
-
query.sort(:version).first
|
58
|
-
end
|
65
|
+
key :version, Integer
|
59
66
|
|
60
|
-
|
61
|
-
|
67
|
+
many :versions,
|
68
|
+
:class_name => "#{self}::#{versioned_class_name}",
|
69
|
+
:foreign_key => versioned_foreign_key,
|
70
|
+
:dependent => :destroy do
|
71
|
+
def earliest
|
72
|
+
query.sort(:version).first
|
73
|
+
end
|
74
|
+
|
75
|
+
def latest
|
76
|
+
query.sort(:version.desc).first
|
77
|
+
end
|
62
78
|
end
|
79
|
+
|
80
|
+
before_save :set_new_version
|
81
|
+
after_save :save_version
|
63
82
|
end
|
64
|
-
model.before_save :set_new_version
|
65
|
-
model.after_save :save_version
|
66
83
|
end
|
67
84
|
|
68
85
|
module InstanceMethods
|
@@ -73,14 +90,14 @@ module MongoMapper
|
|
73
90
|
rev = self.class.versioned_class.new
|
74
91
|
clone_versioned_model(self, rev)
|
75
92
|
rev.version = version
|
76
|
-
rev[self.class.
|
93
|
+
rev[self.class.versioned_foreign_key] = id
|
77
94
|
rev.save!
|
78
95
|
end
|
79
96
|
end
|
80
97
|
|
81
98
|
def revert_to(version)
|
82
99
|
if version.is_a?(self.class.versioned_class)
|
83
|
-
return false unless version[self.class.
|
100
|
+
return false unless version[self.class.versioned_foreign_key] == id and !version.new_record?
|
84
101
|
else
|
85
102
|
return false unless version = versions.where(:version => version).first
|
86
103
|
end
|
@@ -110,11 +127,11 @@ module MongoMapper
|
|
110
127
|
|
111
128
|
def clone_versioned_model(orig_model, new_model)
|
112
129
|
if orig_model.is_a?(self.class.versioned_class)
|
130
|
+
new_model['_type'] = orig_model['_version_type']
|
113
131
|
orig_model = orig_model.changed_attributes
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
new_model = new_model.changed_attributes
|
132
|
+
elsif new_model.is_a?(self.class.versioned_class)
|
133
|
+
new_model['_version_type'] = orig_model['_type']
|
134
|
+
new_model = new_model.changed_attributes
|
118
135
|
end
|
119
136
|
|
120
137
|
self.class.versioned_keys.each do |col|
|
@@ -141,17 +158,17 @@ module MongoMapper
|
|
141
158
|
end
|
142
159
|
|
143
160
|
def next_version
|
144
|
-
|
161
|
+
new_record? || versions.empty? ? 1 : versions.map(&:version).max.next
|
145
162
|
end
|
146
163
|
end
|
147
164
|
|
148
165
|
module ClassMethods
|
149
166
|
def versioned_class
|
150
|
-
const_get
|
167
|
+
const_get versioned_class_name
|
151
168
|
end
|
152
169
|
|
153
170
|
def versioned_keys
|
154
|
-
keys.keys -
|
171
|
+
keys.keys - non_versioned_keys
|
155
172
|
end
|
156
173
|
|
157
174
|
def without_revision
|
@@ -169,13 +186,6 @@ module MongoMapper
|
|
169
186
|
end
|
170
187
|
end
|
171
188
|
end
|
172
|
-
|
173
|
-
def skipped_keys
|
174
|
-
@skipped_keys ||= [
|
175
|
-
'_id', 'created_at', 'updated_at', 'creator_id',
|
176
|
-
'updater_id', 'version', self.class.to_s.foreign_key
|
177
|
-
]
|
178
|
-
end
|
179
189
|
end
|
180
190
|
end
|
181
191
|
end
|
@@ -7,18 +7,25 @@ describe MongoMapper::Acts::Versioned do
|
|
7
7
|
|
8
8
|
plugin MongoMapper::Acts::Versioned
|
9
9
|
|
10
|
-
self.
|
10
|
+
self.non_versioned_keys << 'depth'
|
11
11
|
|
12
12
|
key :title, String
|
13
13
|
key :depth, Integer
|
14
14
|
timestamps!
|
15
15
|
end
|
16
|
+
|
17
|
+
class Sublandmark < Landmark
|
18
|
+
key :location, String
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
it 'should set the correct properties on the version class' do
|
19
23
|
Landmark::Version.original_class.should == Landmark
|
20
24
|
Landmark::Version.collection_name.should == 'landmark_versions'
|
21
25
|
Landmark.versioned_class.should == Landmark::Version
|
26
|
+
Sublandmark::Version.original_class.should == Landmark
|
27
|
+
Sublandmark::Version.collection_name.should == 'landmark_versions'
|
28
|
+
Sublandmark.versioned_class.should == Landmark::Version
|
22
29
|
end
|
23
30
|
|
24
31
|
it 'should save a versioned copy' do
|
@@ -53,7 +60,6 @@ describe MongoMapper::Acts::Versioned do
|
|
53
60
|
(2..10).each do |i|
|
54
61
|
l = Landmark.first
|
55
62
|
l.update_attributes(:title => "title#{i}")
|
56
|
-
l.version.should == i
|
57
63
|
end
|
58
64
|
|
59
65
|
l = l.reload
|
@@ -73,7 +79,6 @@ describe MongoMapper::Acts::Versioned do
|
|
73
79
|
(2..10).each do |i|
|
74
80
|
l = Landmark.first
|
75
81
|
l.update_attributes(:title => "title#{i}")
|
76
|
-
l.version.should == i
|
77
82
|
end
|
78
83
|
|
79
84
|
l = l.reload
|
@@ -93,7 +98,6 @@ describe MongoMapper::Acts::Versioned do
|
|
93
98
|
(2..10).each do |i|
|
94
99
|
l = Landmark.first
|
95
100
|
l.update_attributes(:title => "title#{i}")
|
96
|
-
l.version.should == i
|
97
101
|
end
|
98
102
|
|
99
103
|
l_version = l.reload.versions.last
|
@@ -171,4 +175,57 @@ describe MongoMapper::Acts::Versioned do
|
|
171
175
|
@l.versions[0].next.should == @l.versions[1]
|
172
176
|
end
|
173
177
|
end
|
178
|
+
|
179
|
+
it 'should save a versioned class with sci' do
|
180
|
+
s = Sublandmark.create!(:title => 'first title')
|
181
|
+
s.new_record?.should be_false
|
182
|
+
s.version.should == 1
|
183
|
+
|
184
|
+
s.versions.size.should == 1
|
185
|
+
s.versions.first.should be_a(Landmark.versioned_class)
|
186
|
+
s.versions.first.attributes.keys.should include('_version_type')
|
187
|
+
s.versions.first._version_type.should == 'Sublandmark'
|
188
|
+
s.versions.first.landmark.should == s
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'should rollback with sti' do
|
192
|
+
s = Sublandmark.create(:title => 'title')
|
193
|
+
(2..5).each do |i|
|
194
|
+
s = Sublandmark.first
|
195
|
+
s.update_attributes(:title => "title#{i}")
|
196
|
+
end
|
197
|
+
|
198
|
+
s = s.reload
|
199
|
+
s.version.should == 5
|
200
|
+
s.versions.size.should == 5
|
201
|
+
s.title.should == 'title5'
|
202
|
+
s.revert_to!(3).should be_true
|
203
|
+
s = s.reload
|
204
|
+
s.version.should == 3
|
205
|
+
s.versions.size.should == 5
|
206
|
+
s.title.should == 'title3'
|
207
|
+
|
208
|
+
s.versions.each do |version|
|
209
|
+
version._version_type.should == 'Sublandmark'
|
210
|
+
end
|
211
|
+
|
212
|
+
l = Landmark.create(:title => 'other title')
|
213
|
+
(2..5).each do |i|
|
214
|
+
l = Landmark.first
|
215
|
+
l.update_attributes(:title => "other title#{i}")
|
216
|
+
end
|
217
|
+
|
218
|
+
l = l.reload
|
219
|
+
l.versions.should_not == s.versions
|
220
|
+
l.version.should == 5
|
221
|
+
l.versions.size.should == 5
|
222
|
+
l.title.should == 'other title5'
|
223
|
+
l.revert_to!(3).should be_true
|
224
|
+
l = l.reload
|
225
|
+
l.version.should == 3
|
226
|
+
l.versions.size.should == 5
|
227
|
+
l.title.should == 'other title3'
|
228
|
+
|
229
|
+
Landmark::Version.count.should == 10
|
230
|
+
end
|
174
231
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 4
|
9
|
+
version: 0.0.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Gigamo
|
@@ -40,7 +40,6 @@ extensions: []
|
|
40
40
|
extra_rdoc_files: []
|
41
41
|
|
42
42
|
files:
|
43
|
-
- lib/acts_as_versioned/version.rb
|
44
43
|
- lib/acts_as_versioned.rb
|
45
44
|
- spec/acts_as_versioned_spec.rb
|
46
45
|
- spec/spec_helper.rb
|