controlled_versioning 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Mjk3OGY1NzhhMTZjMzU0NzBkYjE1MjhhZWRiYTdlNmZhZTNiMzFiYg==
4
+ YjYzZmVjOTZmMTM2ZDk2ZmFkNmMwMTMwZDJjOTI1MGI5NjkzNWI1ZA==
5
5
  data.tar.gz: !binary |-
6
- MTg1MzA2ZDA3MzIzOGNkMGY0NDc3ZmM1MmEwYjljOGVjOGIzZjU2Nw==
6
+ ZGM5N2Y0ZGM3Yjg5YjJjYjQ0MWYxNDQxN2M4YzNhZTdkNzRkZjJhNg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MmUzOTBhMmI3NThmOWM3NGFiYWNkMzUwNjJiYjMzN2E1OTJlZmI1ODIyYjRk
10
- NTVkMmQzMWNiMzA5MmVhOTZlZDA1Yjg0NjU4M2U5YmNjNDQ5ZDIxOTc1Zjcy
11
- NDJhMDBhMTgwZTg2OTRhMWIyODJjMzQxZmVkMzAyMzYzODYyYzM=
9
+ ZTMwNjg4OGY0NmIwMzNhZGFlYzgwM2NhOTllZTEyY2NjODhiZDAzMGUyNmQ3
10
+ OGUzNzI0ZTA4OGRmYTAyODg1NjExMjZmNjEyZDQ1YWRiYWEwNTQ1MTQ5OWRm
11
+ ZTQ4MTc1ZmJhMDc1NTQ1MTQyYzA2MGMzN2IwOWM3NWMxZDFiMjM=
12
12
  data.tar.gz: !binary |-
13
- OWVkYTdhMGU5MGI0YzRjN2JmZDRjM2NmMWRhMzU1MjJmNzVjNGQ1OTM1Yzk4
14
- OWNlYzFhYjIwODE0NWUyZjgyYTM0YTkxZWU2ZDcxNmQ3NDZlYjJjMGY5ZWFj
15
- OGRhMWIzM2UxYzVkNjc0NTY3MzlkMGVjZTljY2Y2NDUyOGQzMzQ=
13
+ Y2Y0ZWMyZmM5YTdiYmNjMTA0MGZiNGVjZmJiOGFmNzEyODEwODlhZmViNTMz
14
+ MzYyZDA4YjMwZjU0YTM5NDAyNDk2ZDI0MWU2ZmM0ODgwMTNlMjEwMDc2MDgw
15
+ YzlmOTZmN2NmOTdjNzRjMDIxZmMzYmY0OTFiNmZjYzZiZWJjYmQ=
@@ -20,8 +20,12 @@ module ControlledVersioning
20
20
  update_attributes(pending: false, declined: true) if pending?
21
21
  end
22
22
 
23
- def changes
24
- ChangeTracker.new(self).get_changes
23
+ def versionable_changes
24
+ ChangeTracker.new(self)
25
+ end
26
+
27
+ def is_a_child?
28
+ false
25
29
  end
26
30
  end
27
31
  end
@@ -6,8 +6,16 @@ module ControlledVersioning
6
6
  has_many :version_attributes, as: :version
7
7
  has_many :version_children, as: :version
8
8
 
9
- def changes
10
- ChangeTracker.new(self).get_changes
9
+ def versionable_changes
10
+ ChangeTracker.new(self)
11
+ end
12
+
13
+ def parent
14
+ version
15
+ end
16
+
17
+ def is_a_child?
18
+ true
11
19
  end
12
20
  end
13
21
  end
@@ -4,6 +4,8 @@ require "controlled_versioning/engine"
4
4
  require "controlled_versioning/version"
5
5
 
6
6
  require "controlled_versioning/change_tracker"
7
+ require "controlled_versioning/change_tracker/attribute"
8
+ require "controlled_versioning/change_tracker/child"
7
9
 
8
10
  require "controlled_versioning/initial_version"
9
11
  require "controlled_versioning/initial_version/factory"
@@ -109,18 +111,10 @@ module ControlledVersioning
109
111
  end
110
112
 
111
113
  def submit_revision(suggested_attributes)
112
- assign_attributes(suggested_attributes)
113
- if invalid?
114
- errors
115
- elsif !Revision::Auditor.new(self).changes_original?
116
- errors[:base] << I18n.t("errors.messages.no_revisions_made")
117
- errors
118
- else
119
- version = versions.build
120
- Revision::Factory.new(versionable: self, version: version).build
121
- version.save
122
- version
123
- end
114
+ Revision::Factory.new(
115
+ versionable: self,
116
+ suggested_attributes: suggested_attributes
117
+ ).build_parent
124
118
  end
125
119
 
126
120
  end
@@ -5,28 +5,15 @@ class ChangeTracker < Version
5
5
  @version = version
6
6
  end
7
7
 
8
- def get_changes
9
- changed_attributes.merge(marked_for_removal).merge(changed_children)
8
+ def all
9
+ attributes + children
10
10
  end
11
11
 
12
- private
13
- def changed_attributes
14
- version_attributes.each_with_object({}) do |v, h|
15
- h[v.name] = { new_value: v.new_value, old_value: v.old_value }
16
- end
12
+ def attributes
13
+ version_attributes.collect{ |attr| ChangeTracker::Attribute.new(attr) }
17
14
  end
18
15
 
19
- def marked_for_removal
20
- version.marked_for_removal? ? { marked_for_removal: true } : {}
21
- end
22
-
23
- def changed_children
24
- version_children.each_with_object({}) do |v, h|
25
- if h[v.association_name].present?
26
- h[v.association_name] += [{ id: v.versionable_id}.merge(v.changes)]
27
- else
28
- h[v.association_name] = [{ id: v.versionable_id}.merge(v.changes)]
29
- end
30
- end
16
+ def children
17
+ version_children.collect{ |child| ChangeTracker::Child.new(child) }
31
18
  end
32
19
  end
@@ -0,0 +1,20 @@
1
+ class ChangeTracker::Attribute
2
+
3
+ attr_reader :attr
4
+ def initialize(attr)
5
+ @attr = attr
6
+ end
7
+
8
+ def name
9
+ attr.name
10
+ end
11
+
12
+ def old_value
13
+ attr.old_value
14
+ end
15
+
16
+ def new_value
17
+ attr.new_value
18
+ end
19
+
20
+ end
@@ -0,0 +1,20 @@
1
+ class ChangeTracker::Child < ChangeTracker
2
+
3
+ attr_reader :version
4
+ def initialize(version)
5
+ @version = version
6
+ end
7
+
8
+ def name
9
+ version.association_name
10
+ end
11
+
12
+ def marked_for_removal?
13
+ version.marked_for_removal?
14
+ end
15
+
16
+ def new?
17
+ version.versionable_id.nil?
18
+ end
19
+
20
+ end
@@ -1,28 +1,43 @@
1
1
  class Revision::Factory < Revision
2
2
 
3
- attr_reader :versionable, :version
3
+ attr_reader :versionable, :suggested_attributes
4
+ attr_accessor :version
4
5
  def initialize(args)
5
6
  @versionable = args[:versionable]
6
7
  @version = args[:version]
8
+ @suggested_attributes = args[:suggested_attributes]
7
9
  end
8
10
 
9
- def build
11
+ def build_parent
12
+ versionable.assign_attributes(suggested_attributes)
13
+ if versionable.invalid?
14
+ versionable.errors
15
+ elsif !Revision::Auditor.new(versionable).changes_original?
16
+ versionable.errors[:base] << I18n.t("errors.messages.no_revisions_made")
17
+ versionable.errors
18
+ else
19
+ self.version = versionable.versions.build
20
+ add_notes
21
+ build_associations
22
+ version.save
23
+ version
24
+ end
25
+ end
26
+
27
+ def build_associations
10
28
  mark_for_removal
11
- add_notes
12
29
  build_attributes
13
30
  build_children
14
31
  end
15
32
 
16
33
  private
17
- def mark_for_removal
18
- version.marked_for_removal = true if versionable.marked_for_destruction?
34
+ def add_notes
35
+ version.notes = versionable_notes
36
+ version.user = versionable_user
19
37
  end
20
38
 
21
- def add_notes
22
- unless versionable_is_a_nested_association?
23
- version.notes = versionable_notes
24
- version.user = versionable_user
25
- end
39
+ def mark_for_removal
40
+ version.marked_for_removal = true if versionable.marked_for_destruction?
26
41
  end
27
42
 
28
43
  def build_attributes
@@ -52,17 +67,16 @@ class Revision::Factory < Revision
52
67
  def build_child(child, association)
53
68
  if Revision::Auditor.new(child).changes_original?
54
69
  version_child = build_version_child(child, association)
55
- Revision::Factory.new(versionable: child, version: version_child).build
70
+ Revision::Factory.new(
71
+ versionable: child,
72
+ version: version_child
73
+ ).build_associations
56
74
  end
57
75
  end
58
76
 
59
77
  def build_version_child(child, association)
60
78
  version_child = version_children.build(association_name: association)
61
- if child.new_record?
62
- version_child.versionable_type = child.class.name
63
- else
64
- version_child.versionable = child
65
- end
79
+ version_child.versionable = child unless child.new_record?
66
80
  version_child
67
81
  end
68
82
 
@@ -21,8 +21,8 @@ class Revision::Publisher < Revision
21
21
  end
22
22
 
23
23
  def create_versionable
24
- version.versionable = version.versionable_type.constantize.
25
- create(new_attributes)
24
+ version.versionable = version.parent.versionable.public_send(
25
+ version.association_name).create(new_attributes)
26
26
  end
27
27
 
28
28
  def update_versionable
@@ -1,3 +1,3 @@
1
1
  module ControlledVersioning
2
- VERSION_NUMBER = "0.8.0"
2
+ VERSION_NUMBER = "0.9.0"
3
3
  end
@@ -65,8 +65,8 @@ describe "ControlledVersioning" do
65
65
  end
66
66
 
67
67
  it 'returns the initial version' do
68
- @resource.versions.create
69
- @resource.versions.create
68
+ @resource.submit_revision(r_string: "new string")
69
+ @resource.submit_revision(r_float: 63.5)
70
70
  expect(@resource.initial_version).to eq(
71
71
  @resource.versions.find_by(initial: true))
72
72
  end
@@ -230,23 +230,6 @@ describe "ControlledVersioning" do
230
230
  expect(@first_child_resource.r_string).to eq "new string"
231
231
  expect(@second_child_resource.r_string).to eq "second new string"
232
232
  end
233
-
234
- it 'returns a hash of changed attributes for the full family' do
235
- expect(@version.changes).to eq "child_resources" => [
236
- { id: @second_child_resource.id,
237
- "r_string" => {
238
- new_value: "second new string",
239
- old_value: "my string"
240
- }
241
- },
242
- { id: @first_child_resource.id,
243
- "r_string" => {
244
- new_value: "new string",
245
- old_value: "my string"
246
- }
247
- }
248
- ]
249
- end
250
233
  end
251
234
 
252
235
  context 'handles revision for deeply nested children' do
@@ -277,15 +260,6 @@ describe "ControlledVersioning" do
277
260
  @first_grand_child_resource.reload
278
261
  expect(@first_grand_child_resource.r_string).to eq "new string"
279
262
  end
280
-
281
- it 'returns a hash of changed attributes for the full family' do
282
- expect(@version.changes).to eq "child_resources" => [{ id:
283
- @first_child_resource.id, "grand_child_resources" => [{ id:
284
- @first_grand_child_resource.id, "r_string" => { new_value:
285
- "new string", old_value: "my string" }
286
- }]
287
- }]
288
- end
289
263
  end
290
264
 
291
265
  context 'handles new children' do
@@ -312,14 +286,6 @@ describe "ControlledVersioning" do
312
286
  @resource.reload
313
287
  expect(@resource.child_resources.find_by(r_float: 14.0)).to_not be_nil
314
288
  end
315
-
316
- it 'returns a hash of attributes for new children' do
317
- expect(@version.changes).to eq "child_resources" => [{ id:
318
- nil, "r_float" => { new_value: "14.0", old_value: nil },
319
- "parent_resource_id" => { new_value: @resource.id.to_s,
320
- old_value: nil}
321
- }]
322
- end
323
289
  end
324
290
 
325
291
  context 'handles child destruction' do
@@ -350,12 +316,6 @@ describe "ControlledVersioning" do
350
316
  @resource.reload
351
317
  expect(@resource.child_resources.length).to eq 2
352
318
  end
353
-
354
- it 'returns a hash noting marked children' do
355
- expect(@version.changes).to eq "child_resources" => [{ id:
356
- @first_child_resource.id, marked_for_removal: true
357
- }]
358
- end
359
319
  end
360
320
  end
361
321
 
@@ -2,12 +2,90 @@ require 'spec_helper'
2
2
 
3
3
  describe ControlledVersioning::Version do
4
4
 
5
- it 'returns a hash of changed attributes' do
6
- resource = create(:versionable_resource)
7
- version = resource.submit_revision(r_string: "new string", r_float: 90.1)
8
- expect(version.changes).to eq "r_string" => { new_value: "new string",
9
- old_value: "my string" }, "r_float" => { new_value: "90.1",
10
- old_value: "3.14" }
5
+ context 'returns a hash of' do
6
+ before :each do
7
+ @resource = ParentResource.create_with_version({ r_string: "my string",
8
+ r_float: 3.14, child_resources_attributes: [
9
+ { r_string: "my string", r_float: 3.14,
10
+ grand_child_resources_attributes: [
11
+ { r_string: "my string", r_float: 3.14 },
12
+ { r_string: "my string", r_float: 3.14 },
13
+ { r_string: "my string", r_float: 3.14 }
14
+ ] },
15
+ { r_string: "my string", r_float: 3.14,
16
+ grand_child_resources_attributes: [
17
+ { r_string: "my string", r_float: 3.14 },
18
+ { r_string: "my string", r_float: 3.14 },
19
+ { r_string: "my string", r_float: 3.14 }
20
+ ] },
21
+ { r_string: "my string", r_float: 3.14,
22
+ grand_child_resources_attributes: [
23
+ { r_string: "my string", r_float: 3.14 },
24
+ { r_string: "my string", r_float: 3.14 },
25
+ { r_string: "my string", r_float: 3.14 }
26
+ ] }
27
+ ] })
28
+ end
29
+
30
+ it 'changed attributes' do
31
+ version = @resource.submit_revision(r_string: "new string")
32
+ changed_attribute = version.versionable_changes.attributes.first
33
+ expect(changed_attribute.name).to eq "r_string"
34
+ expect(changed_attribute.old_value).to eq "my string"
35
+ expect(changed_attribute.new_value).to eq "new string"
36
+ end
37
+
38
+ it 'changed children' do
39
+ first_child_resource = @resource.child_resources[0]
40
+ version = @resource.submit_revision(child_resources_attributes: [
41
+ {id: first_child_resource.id, r_string: "new string"}
42
+ ])
43
+ changed_child = version.versionable_changes.children.first
44
+ changed_attribute = changed_child.attributes.first
45
+ expect(changed_child.name).to eq "child_resources"
46
+ expect(changed_attribute.name).to eq "r_string"
47
+ expect(changed_attribute.old_value).to eq "my string"
48
+ expect(changed_attribute.new_value).to eq "new string"
49
+ end
50
+
51
+ it 'changed deeply nested children' do
52
+ first_child_resource = @resource.child_resources[0]
53
+ first_grand_child_resource = first_child_resource.
54
+ grand_child_resources.first
55
+ version = @resource.submit_revision(child_resources_attributes: [
56
+ {id: first_child_resource.id, grand_child_resources_attributes: [
57
+ {id: first_grand_child_resource.id, r_string: "new string"}
58
+ ]}
59
+ ])
60
+ changed_child = version.versionable_changes.children.first
61
+ changed_grand_child = changed_child.children.first
62
+ changed_attribute = changed_grand_child.attributes.first
63
+ expect(changed_grand_child.name).to eq "grand_child_resources"
64
+ expect(changed_attribute.name).to eq "r_string"
65
+ expect(changed_attribute.old_value).to eq "my string"
66
+ expect(changed_attribute.new_value).to eq "new string"
67
+ end
68
+
69
+ it 'new children' do
70
+ version = @resource.submit_revision(child_resources_attributes: [
71
+ {r_float: 3.14}
72
+ ])
73
+ changed_child = version.versionable_changes.children.first
74
+ changed_attribute = changed_child.attributes.first
75
+ expect(changed_child.new?).to be_true
76
+ expect(changed_attribute.name).to eq "r_float"
77
+ expect(changed_attribute.old_value).to be_nil
78
+ expect(changed_attribute.new_value).to eq "3.14"
79
+ end
80
+
81
+ it 'marked children' do
82
+ first_child_resource = @resource.child_resources[0]
83
+ version = @resource.submit_revision(child_resources_attributes: [
84
+ {id: first_child_resource.id, _destroy: true}
85
+ ])
86
+ changed_child = version.versionable_changes.children.first
87
+ expect(changed_child.marked_for_removal?).to be_true
88
+ end
11
89
  end
12
90
 
13
91
  context 'has a scope that' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: controlled_versioning
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - timothythehuman
@@ -133,6 +133,8 @@ files:
133
133
  - db/migrate/20140206204920_create_controlled_versioning_version_children.rb
134
134
  - lib/controlled_versioning.rb
135
135
  - lib/controlled_versioning/change_tracker.rb
136
+ - lib/controlled_versioning/change_tracker/attribute.rb
137
+ - lib/controlled_versioning/change_tracker/child.rb
136
138
  - lib/controlled_versioning/engine.rb
137
139
  - lib/controlled_versioning/initial_version.rb
138
140
  - lib/controlled_versioning/initial_version/factory.rb
@@ -229,62 +231,62 @@ specification_version: 4
229
231
  summary: Adds model versioning to a Rails app, with the ability to approve and declined
230
232
  revisions.
231
233
  test_files:
232
- - spec/spec_helper.rb
233
- - spec/factories/parent_resources.rb
234
- - spec/factories/partially_inclusive_versionable_resources.rb
235
- - spec/factories/unversionable_resources.rb
236
- - spec/factories/grand_child_resources.rb
237
- - spec/factories/users.rb
238
- - spec/factories/versionable_resources.rb
239
- - spec/factories/child_resources.rb
240
- - spec/factories/partially_exclusive_versionable_resources.rb
241
234
  - spec/models/controlled_versioning/version_spec.rb
242
- - spec/controlled_versioning_spec.rb
243
- - spec/dummy/config/database.yml
244
- - spec/dummy/config/initializers/session_store.rb
245
- - spec/dummy/config/initializers/secret_token.rb
246
- - spec/dummy/config/initializers/wrap_parameters.rb
247
- - spec/dummy/config/initializers/filter_parameter_logging.rb
248
- - spec/dummy/config/initializers/inflections.rb
249
- - spec/dummy/config/initializers/mime_types.rb
250
- - spec/dummy/config/initializers/backtrace_silencers.rb
251
- - spec/dummy/config/application.rb
252
- - spec/dummy/config/environment.rb
253
- - spec/dummy/config/boot.rb
254
- - spec/dummy/config/routes.rb
255
- - spec/dummy/config/environments/development.rb
256
- - spec/dummy/config/environments/test.rb
257
- - spec/dummy/config/environments/production.rb
258
- - spec/dummy/config/locales/en.yml
259
- - spec/dummy/Rakefile
260
- - spec/dummy/bin/rake
261
- - spec/dummy/bin/bundle
262
- - spec/dummy/bin/rails
235
+ - spec/dummy/public/500.html
263
236
  - spec/dummy/public/422.html
264
- - spec/dummy/public/favicon.ico
265
237
  - spec/dummy/public/404.html
266
- - spec/dummy/public/500.html
267
- - spec/dummy/app/controllers/application_controller.rb
268
- - spec/dummy/app/helpers/application_helper.rb
269
- - spec/dummy/app/models/child_resource.rb
238
+ - spec/dummy/public/favicon.ico
239
+ - spec/dummy/bin/rails
240
+ - spec/dummy/bin/rake
241
+ - spec/dummy/bin/bundle
242
+ - spec/dummy/app/models/partially_inclusive_versionable_resource.rb
243
+ - spec/dummy/app/models/parent_resource.rb
244
+ - spec/dummy/app/models/grand_child_resource.rb
270
245
  - spec/dummy/app/models/nonversionable_resource.rb
271
246
  - spec/dummy/app/models/versionable_resource.rb
272
- - spec/dummy/app/models/grand_child_resource.rb
247
+ - spec/dummy/app/models/child_resource.rb
273
248
  - spec/dummy/app/models/partially_exclusive_versionable_resource.rb
274
- - spec/dummy/app/models/parent_resource.rb
275
249
  - spec/dummy/app/models/user.rb
276
- - spec/dummy/app/models/partially_inclusive_versionable_resource.rb
250
+ - spec/dummy/app/helpers/application_helper.rb
277
251
  - spec/dummy/app/views/layouts/application.html.erb
278
252
  - spec/dummy/app/assets/javascripts/application.js
279
253
  - spec/dummy/app/assets/stylesheets/application.css
254
+ - spec/dummy/app/controllers/application_controller.rb
280
255
  - spec/dummy/config.ru
256
+ - spec/dummy/config/database.yml
257
+ - spec/dummy/config/environments/test.rb
258
+ - spec/dummy/config/environments/development.rb
259
+ - spec/dummy/config/environments/production.rb
260
+ - spec/dummy/config/environment.rb
261
+ - spec/dummy/config/application.rb
262
+ - spec/dummy/config/initializers/secret_token.rb
263
+ - spec/dummy/config/initializers/filter_parameter_logging.rb
264
+ - spec/dummy/config/initializers/inflections.rb
265
+ - spec/dummy/config/initializers/mime_types.rb
266
+ - spec/dummy/config/initializers/backtrace_silencers.rb
267
+ - spec/dummy/config/initializers/session_store.rb
268
+ - spec/dummy/config/initializers/wrap_parameters.rb
269
+ - spec/dummy/config/boot.rb
270
+ - spec/dummy/config/locales/en.yml
271
+ - spec/dummy/config/routes.rb
281
272
  - spec/dummy/README.rdoc
282
- - spec/dummy/db/schema.rb
273
+ - spec/dummy/Rakefile
274
+ - spec/dummy/db/migrate/20140117222842_create_grand_child_resources.rb
275
+ - spec/dummy/db/migrate/20140117222814_create_partially_inclusive_versionable_resources.rb
276
+ - spec/dummy/db/migrate/20140117222840_create_parent_resources.rb
277
+ - spec/dummy/db/migrate/20140117222828_create_nonversionable_resources.rb
283
278
  - spec/dummy/db/migrate/20140117222815_create_partially_exclusive_versionable_resources.rb
284
279
  - spec/dummy/db/migrate/20140117222808_create_versionable_resources.rb
285
- - spec/dummy/db/migrate/20140117222840_create_parent_resources.rb
286
280
  - spec/dummy/db/migrate/20140117222800_create_users.rb
287
- - spec/dummy/db/migrate/20140117222842_create_grand_child_resources.rb
288
281
  - spec/dummy/db/migrate/20140117222841_create_child_resources.rb
289
- - spec/dummy/db/migrate/20140117222814_create_partially_inclusive_versionable_resources.rb
290
- - spec/dummy/db/migrate/20140117222828_create_nonversionable_resources.rb
282
+ - spec/dummy/db/schema.rb
283
+ - spec/factories/partially_inclusive_versionable_resources.rb
284
+ - spec/factories/unversionable_resources.rb
285
+ - spec/factories/versionable_resources.rb
286
+ - spec/factories/parent_resources.rb
287
+ - spec/factories/grand_child_resources.rb
288
+ - spec/factories/partially_exclusive_versionable_resources.rb
289
+ - spec/factories/users.rb
290
+ - spec/factories/child_resources.rb
291
+ - spec/controlled_versioning_spec.rb
292
+ - spec/spec_helper.rb