mongo_mapper_acts_as_versioned 0.0.4 → 0.0.10

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # ActsAsVersioned for [MongoMapper](http://github.com/jnunemaker/mongomapper)
2
2
 
3
- Basic MongoMapper port of technoweenie's [acts_as_versioned](http://github.com/technoweenie/acts_as_versioned). Stores changed attributes in a Hash key instead of copying all keys from the original model.
3
+ Basic MongoMapper port of technoweenie's [acts_as_versioned](http://github.com/technoweenie/acts_as_versioned). Stores changed attributes in a Hash key inside an Embedded Document instead of copying all keys from the original model.
4
4
 
5
5
  ## Usage
6
6
 
@@ -1,108 +1,55 @@
1
1
  module MongoMapper
2
2
  module Acts
3
3
  module Versioned
4
- VERSION = '0.0.4'
5
- CALLBACKS = [:set_new_version, :save_version, :save_version?]
4
+ VERSION = '0.0.10'
5
+ CALLBACKS = [:save_version, :save_version?]
6
6
 
7
7
  def self.configure(model)
8
8
  model.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
- ]
9
+ cattr_accessor :versioned_class_name, :non_versioned_keys
20
10
 
21
- const_set(versioned_class_name, Class.new).class_eval do
22
- include MongoMapper::Document
23
-
24
- class << self
25
- delegate :versioned_foreign_key, :to => :original_class
26
- end
27
-
28
- key :version, Integer
29
- key :changed_attributes, Hash
30
-
31
- if type_key = keys['_type']
32
- key :_version_type, type_key.type, type_key.options
33
- end
34
-
35
- def self.before(version)
36
- where(
37
- versioned_foreign_key => version[versioned_foreign_key],
38
- :version.lt => version.version
39
- ).sort(:version.desc).first
40
- end
41
-
42
- def self.after(version)
43
- where(
44
- versioned_foreign_key => version[versioned_foreign_key],
45
- :version.gt => version.version
46
- ).sort(:version.asc).first
47
- end
11
+ self.versioned_class_name = :Version
12
+ self.non_versioned_keys = %w(
13
+ _id _type created_at updated_at creator_id updater_id version
14
+ )
48
15
 
49
- def previous
50
- self.class.before(self)
51
- end
16
+ const_set(versioned_class_name, Class.new).class_eval do
17
+ include MongoMapper::EmbeddedDocument
52
18
 
53
- def next
54
- self.class.after(self)
55
- end
19
+ key :version, Integer
20
+ key :modified, Hash
56
21
  end
57
22
 
58
- versioned_class.cattr_accessor :original_class
59
- versioned_class.original_class = self
60
- versioned_class.set_collection_name versioned_collection_name
61
- versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
62
- :class_name => self.to_s,
63
- :foreign_key => versioned_foreign_key
64
-
65
- key :version, Integer
66
-
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
23
+ many :versions, :class => "#{self}::#{versioned_class_name}".constantize do
24
+ def [](given_version)
25
+ detect {|version| version.version.to_s == given_version.to_s }
77
26
  end
78
27
  end
79
-
80
- before_save :set_new_version
81
- after_save :save_version
82
28
  end
29
+
30
+ model.key :version, Integer
31
+ model.before_save :save_version
83
32
  end
84
33
 
85
34
  module InstanceMethods
86
35
  def save_version
87
- if @saving_version
88
- @saving_version = nil
89
-
36
+ if new_record? || save_version?
37
+ self.version = next_version
90
38
  rev = self.class.versioned_class.new
91
- clone_versioned_model(self, rev)
39
+ clone_attributes(self, rev)
92
40
  rev.version = version
93
- rev[self.class.versioned_foreign_key] = id
94
- rev.save!
41
+ self.versions << rev
95
42
  end
96
43
  end
97
44
 
98
45
  def revert_to(version)
99
46
  if version.is_a?(self.class.versioned_class)
100
- return false unless version[self.class.versioned_foreign_key] == id and !version.new_record?
47
+ return false if version.new_record?
101
48
  else
102
- return false unless version = versions.where(:version => version).first
49
+ return false unless version = versions[version]
103
50
  end
104
51
 
105
- clone_versioned_model(version, self)
52
+ clone_attributes(version, self)
106
53
  self.version = version.version
107
54
 
108
55
  true
@@ -125,17 +72,15 @@ module MongoMapper
125
72
  end
126
73
  end
127
74
 
128
- def clone_versioned_model(orig_model, new_model)
75
+ def clone_attributes(orig_model, new_model)
129
76
  if orig_model.is_a?(self.class.versioned_class)
130
- new_model['_type'] = orig_model['_version_type']
131
- orig_model = orig_model.changed_attributes
77
+ orig_model = orig_model.modified
132
78
  elsif new_model.is_a?(self.class.versioned_class)
133
- new_model['_version_type'] = orig_model['_type']
134
- new_model = new_model.changed_attributes
79
+ new_model = new_model.modified
135
80
  end
136
81
 
137
- self.class.versioned_keys.each do |col|
138
- new_model[col] = orig_model[col]
82
+ self.class.versioned_keys.each do |attribute|
83
+ new_model[attribute] = orig_model[attribute]
139
84
  end
140
85
  end
141
86
 
@@ -152,11 +97,6 @@ module MongoMapper
152
97
 
153
98
  protected
154
99
 
155
- def set_new_version
156
- @saving_version = new_record? || save_version?
157
- self.version = next_version if @saving_version
158
- end
159
-
160
100
  def next_version
161
101
  new_record? || versions.empty? ? 1 : versions.map(&:version).max.next
162
102
  end
@@ -1,231 +1,222 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe MongoMapper::Acts::Versioned do
4
- before :all do
5
- class Landmark
6
- include MongoMapper::Document
4
+ context 'landmarks and generally' do
5
+ before :all do
6
+ class Landmark
7
+ include MongoMapper::Document
7
8
 
8
- plugin MongoMapper::Acts::Versioned
9
+ plugin MongoMapper::Acts::Versioned
9
10
 
10
- self.non_versioned_keys << 'depth'
11
+ self.non_versioned_keys << 'depth'
11
12
 
12
- key :title, String
13
- key :depth, Integer
14
- timestamps!
13
+ key :title, String
14
+ key :depth, Integer
15
+ timestamps!
16
+ end
17
+
18
+ class Sublandmark < Landmark
19
+ key :location, String
20
+ end
15
21
  end
16
22
 
17
- class Sublandmark < Landmark
18
- key :location, String
23
+ it 'should set the correct properties on the version class' do
24
+ Landmark.versioned_class.should == Landmark::Version
25
+ Sublandmark.versioned_class.should == Landmark::Version
19
26
  end
20
- end
21
27
 
22
- it 'should set the correct properties on the version class' do
23
- Landmark::Version.original_class.should == Landmark
24
- Landmark::Version.collection_name.should == 'landmark_versions'
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
29
- end
28
+ it 'should save a versioned copy' do
29
+ l = Landmark.create(:title => 'title')
30
+ l.new_record?.should be_false
31
+ l.versions.size.should == 1
32
+ l.version.should == 1
33
+ l.versions.first.should be_a(Landmark.versioned_class)
34
+ end
30
35
 
31
- it 'should save a versioned copy' do
32
- l = Landmark.create(:title => 'title')
33
- l.new_record?.should be_false
34
- l.versions.size.should == 1
35
- l.version.should == 1
36
- l.versions.first.should be_a(Landmark.versioned_class)
37
- end
36
+ it 'should save without revision' do
37
+ l = Landmark.create(:title => 'title')
38
+ l.version.should == 1
38
39
 
39
- it 'should save without revision' do
40
- l = Landmark.create(:title => 'title')
41
- l.version.should == 1
40
+ l.update_attributes(:title => 'changed')
41
+ l = l.reload
42
+ l.version.should == 2
42
43
 
43
- l.update_attributes(:title => 'changed')
44
- l = l.reload
45
- l.version.should == 2
44
+ old_versions = l.versions.size
46
45
 
47
- old_versions = l.versions.size
46
+ l.save_without_revision
48
47
 
49
- l.save_without_revision
48
+ l.without_revision do
49
+ l.update_attributes :title => 'changed again'
50
+ end
50
51
 
51
- l.without_revision do
52
- l.update_attributes :title => 'changed again'
52
+ l.reload.versions.size.should == old_versions
53
53
  end
54
54
 
55
- l.reload.versions.size.should == old_versions
56
- end
55
+ it 'should rollback with version number' do
56
+ l = Landmark.create(:title => 'title')
57
+ (2..10).each do |i|
58
+ l = Landmark.first
59
+ l.update_attributes(:title => "title#{i}")
60
+ end
57
61
 
58
- it 'should rollback with version number' do
59
- l = Landmark.create(:title => 'title')
60
- (2..10).each do |i|
61
- l = Landmark.first
62
- l.update_attributes(:title => "title#{i}")
62
+ l = l.reload
63
+ l.version.should == 10
64
+ l.versions.size.should == 10
65
+ l.title.should == 'title10'
66
+
67
+ l.revert_to!(7).should be_true
68
+ l = l.reload
69
+ l.version.should == 7
70
+ l.versions.size.should == 10
71
+ l.title.should == 'title7'
63
72
  end
64
73
 
65
- l = l.reload
66
- l.version.should == 10
67
- l.versions.size.should == 10
68
- l.title.should == 'title10'
74
+ it 'should rollback with version class' do
75
+ l = Landmark.create(:title => 'title')
76
+ (2..10).each do |i|
77
+ l = Landmark.first
78
+ l.update_attributes(:title => "title#{i}")
79
+ end
69
80
 
70
- l.revert_to!(7).should be_true
71
- l = l.reload
72
- l.version.should == 7
73
- l.versions.size.should == 10
74
- l.title.should == 'title7'
75
- end
81
+ l = l.reload
82
+ l.version.should == 10
83
+ l.versions.size.should == 10
84
+ l.title.should == 'title10'
76
85
 
77
- it 'should rollback with version class' do
78
- l = Landmark.create(:title => 'title')
79
- (2..10).each do |i|
80
- l = Landmark.first
81
- l.update_attributes(:title => "title#{i}")
86
+ l.revert_to!(l.versions[7]).should be_true
87
+ l = l.reload
88
+ l.version.should == 7
89
+ l.versions.size.should == 10
90
+ l.title.should == 'title7'
82
91
  end
83
92
 
84
- l = l.reload
85
- l.version.should == 10
86
- l.versions.size.should == 10
87
- l.title.should == 'title10'
93
+ it 'should have versioned records belong to its parent' do
94
+ l = Landmark.create(:title => 'title')
95
+ (2..10).each do |i|
96
+ l = Landmark.first
97
+ l.update_attributes(:title => "title#{i}")
98
+ end
88
99
 
89
- l.revert_to!(l.versions.find_by_version(7)).should be_true
90
- l = l.reload
91
- l.version.should == 7
92
- l.versions.size.should == 10
93
- l.title.should == 'title7'
94
- end
100
+ l_version = l.reload.versions.last
101
+ l_version._root_document.should == l.reload
102
+ end
95
103
 
96
- it 'should have versioned records belong to its parent' do
97
- l = Landmark.create(:title => 'title')
98
- (2..10).each do |i|
99
- l = Landmark.first
100
- l.update_attributes(:title => "title#{i}")
104
+ it 'should not create new versions for skipped keys' do
105
+ l = Landmark.create(:title => 'title')
106
+ l.update_attributes(:depth => 1)
107
+ l = l.reload
108
+ l.version.should == 1
109
+ l.versions.size.should == 1
101
110
  end
102
111
 
103
- l_version = l.reload.versions.last
104
- l_version.landmark.should == l.reload
105
- end
112
+ it 'should create a new version even if a skipped key is added' do
113
+ l = Landmark.create(:title => 'title')
114
+ l.update_attributes(:title => 'new title', :depth => 1)
115
+ l = l.reload
116
+ l.version.should == 2
117
+ l.versions.size.should == 2
118
+ end
106
119
 
107
- it 'should not create new versions for skipped keys' do
108
- l = Landmark.create(:title => 'title')
109
- l.update_attributes(:depth => 1)
110
- l = l.reload
111
- l.version.should == 1
112
- l.versions.size.should == 1
113
- end
120
+ it 'should remember skipped keys through versions' do
121
+ l = Landmark.create(:title => 'title')
122
+ l.update_attributes(:title => 'new title')
123
+ l = l.reload
124
+ l.version.should == 2
125
+ l.versions.size.should == 2
126
+
127
+ l.update_attributes(:depth => 1)
128
+ l = l.reload
129
+ l.version.should == 2
130
+ l.versions.size.should == 2
131
+ l.depth.should == 1
132
+ l.title.should == 'new title'
133
+
134
+ l.revert_to!(1)
135
+ l = l.reload
136
+ l.version.should == 1
137
+ l.versions.size.should == 2
138
+ l.depth.should == 1
139
+ l.title.should == 'title'
140
+ end
114
141
 
115
- it 'should create a new version even if a skipped key is added' do
116
- l = Landmark.create(:title => 'title')
117
- l.update_attributes(:title => 'new title', :depth => 1)
118
- l = l.reload
119
- l.version.should == 2
120
- l.versions.size.should == 2
121
- end
142
+ it 'should store changes in a hash' do
143
+ l = Landmark.create(:title => 'title')
144
+ l.versions[1].modified.should == {'title' => 'title'}
122
145
 
123
- it 'should remember skipped keys through versions' do
124
- l = Landmark.create(:title => 'title')
125
- l.update_attributes(:title => 'new title')
126
- l = l.reload
127
- l.version.should == 2
128
- l.versions.size.should == 2
129
-
130
- l.update_attributes(:depth => 1)
131
- l = l.reload
132
- l.version.should == 2
133
- l.versions.size.should == 2
134
- l.depth.should == 1
135
- l.title.should == 'new title'
136
-
137
- l.revert_to!(1)
138
- l = l.reload
139
- l.version.should == 1
140
- l.versions.size.should == 2
141
- l.depth.should == 1
142
- l.title.should == 'title'
143
- end
146
+ l.update_attributes(:title => 'changed title', :depth => 1)
147
+ l.reload.versions[2].modified.should == {'title' => 'changed title'}
148
+ end
144
149
 
145
- it 'should store changes in a hash' do
146
- l = Landmark.create(:title => 'title')
147
- l.versions[0].changed_attributes.should == {'title' => 'title'}
150
+ it 'should save a versioned class with sci' do
151
+ s = Sublandmark.create!(:title => 'first title')
152
+ s.new_record?.should be_false
153
+ s.version.should == 1
148
154
 
149
- l.update_attributes(:title => 'changed title', :depth => 1)
150
- l.reload.versions[1].changed_attributes.should == {'title' => 'changed title'}
151
- end
155
+ s.versions.size.should == 1
156
+ s.versions.first.should be_a(Landmark.versioned_class)
157
+ s.versions.first._root_document.should == s
158
+ end
152
159
 
153
- context 'finders' do
154
- before :each do
155
- @l = Landmark.create(:title => 'title')
160
+ it 'should rollback with sci' do
161
+ l = Landmark.create(:title => 'other title')
156
162
  (2..5).each do |i|
157
- Landmark.first.update_attributes(:title => "title#{i}")
163
+ l = Landmark.first
164
+ l.update_attributes(:title => "other title#{i}")
158
165
  end
159
- @l = @l.reload
160
- end
161
-
162
- it 'should find the earliest version' do
163
- @l.versions.earliest.should == @l.versions.find_by_version(1)
164
- end
165
-
166
- it 'should find the latest version' do
167
- @l.versions.latest.should == @l.versions.find_by_version(5)
168
- end
169
166
 
170
- it 'should find the previous version' do
171
- @l.versions[1].previous.should == @l.versions[0]
172
- end
167
+ l = l.reload
168
+ l.version.should == 5
169
+ l.versions.size.should == 5
170
+ l.title.should == 'other title5'
171
+ l.revert_to!(3).should be_true
172
+ l = l.reload
173
+ l.version.should == 3
174
+ l.versions.size.should == 5
175
+ l.title.should == 'other title3'
176
+
177
+ s = Sublandmark.create(:title => 'title')
178
+ (2..5).each do |i|
179
+ s = Sublandmark.first
180
+ s.update_attributes(:title => "title#{i}")
181
+ end
173
182
 
174
- it 'should find the next version' do
175
- @l.versions[0].next.should == @l.versions[1]
183
+ s = s.reload
184
+ s.versions.should_not == l.versions
185
+ s.version.should == 5
186
+ s.versions.size.should == 5
187
+ s.title.should == 'title5'
188
+ s.revert_to!(3).should be_true
189
+ s = s.reload
190
+ s.version.should == 3
191
+ s.versions.size.should == 5
192
+ s.title.should == 'title3'
176
193
  end
177
194
  end
178
195
 
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
196
+ context 'nodes' do
197
+ before :all do
198
+ class Node
199
+ include MongoMapper::Document
183
200
 
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
201
+ key :title, String
202
+ end
190
203
 
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
204
+ class Page < Node
205
+ plugin MongoMapper::Acts::Versioned
206
+ end
197
207
 
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'
208
+ class Post < Node
209
+ plugin MongoMapper::Acts::Versioned
210
+ end
210
211
  end
211
212
 
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}")
213
+ it 'should version only the subclass' do
214
+ page = Page.create(:title => 'page title')
215
+ post = Post.create(:title => 'post title')
216
+ page.version.should == 1
217
+ page.versions.size.should == 1
218
+ post.version.should == 1
219
+ post.versions.size.should == 1
216
220
  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
221
  end
231
222
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 10
9
+ version: 0.0.10
10
10
  platform: ruby
11
11
  authors:
12
12
  - Gigamo
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-08-27 00:00:00 +02:00
17
+ date: 2010-09-12 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency