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 CHANGED
@@ -43,11 +43,13 @@ Default ignored keys are:
43
43
  * "creator\_id"
44
44
  * "updater\_id"
45
45
  * "version"
46
- * the versioned class' foreign key
46
+ * "\_type"
47
+ * "\_versioned\_type"
48
+ * versioned\_foreign\_key
47
49
 
48
50
  ### Ignoring additional keys
49
51
 
50
- Simply add `self.skipped_keys << 'new_skipped_key'` somewhere in your model.
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
 
@@ -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
- const_set(:Version, Class.new).class_eval do
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
- super_foreign_key => version[super_foreign_key],
17
- :version.lt => version.version
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
- super_foreign_key => version[super_foreign_key],
24
- :version.gt => version.version
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 "#{self.collection_name.singularize}_versions"
60
+ versioned_class.set_collection_name versioned_collection_name
48
61
  versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
49
- :class_name => "::#{self}",
50
- :foreign_key => self.to_s.foreign_key
51
- end
62
+ :class_name => self.to_s,
63
+ :foreign_key => versioned_foreign_key
52
64
 
53
- model.key :version, Integer
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
- def latest
61
- query.sort(:version.desc).first
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.to_s.foreign_key] = id
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.to_s.foreign_key] == id and !version.new_record?
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
- end
115
-
116
- if new_model.is_a?(self.class.versioned_class)
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
- (new_record? ? 0 : versions.map(&:version).max) + 1
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(:Version)
167
+ const_get versioned_class_name
151
168
  end
152
169
 
153
170
  def versioned_keys
154
- keys.keys - skipped_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.skipped_keys << 'depth'
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
- - 3
9
- version: 0.0.3
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
@@ -1,7 +0,0 @@
1
- module MongoMapper
2
- module Acts
3
- module Versioned
4
- VERSION = '0.0.3'
5
- end
6
- end
7
- end