versioned_record 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 485621958b932f0a1c13be6a89eeb6b915434363
4
- data.tar.gz: c5ffe378f6cb1d2685a4fa8db6e65028c3baf157
3
+ metadata.gz: 922578eddd43ab7241f9508f1e2b69df72348a78
4
+ data.tar.gz: b6016c21345c767d7ad00c5a8ff56655ec69af9e
5
5
  SHA512:
6
- metadata.gz: fea26e33efb1a2f4dd5f458faa26f6b74dfb19aebe1288119c4a1a90f84d2635c8d276675d82682ec19429d9958c52a6ed2637959cd89c8fb8172a8bbef29ae5
7
- data.tar.gz: c4d33837fd8d60858131fdecda9268a9911f565eb86adf8d7455cfc5aeb0a1bb81731c8fefdff55c67be9fb134f05f842786581f482f01cc0882e3cc9ef7dc4d
6
+ metadata.gz: 5f45e23784fb7e5924a0baedcf5b2efdd18eb8a5eaabeb4b8c5455c77c5f434e1ebd3706125978e78276af607b37fe75cfc726c17c4db7d5c2e5ce9097d09428
7
+ data.tar.gz: c1558526c1ba918b7741279b90cb60b5e4312f3585a53f8e8f9c84e64abef9695dd6d2907068ce3e42f43a021dd6fd26a6956583eec80f0fe9750b97a793b7c9
data/README.md CHANGED
@@ -82,22 +82,18 @@ A simple `belongs_to` will work as normal but will always refer to the latest ve
82
82
 
83
83
  `belongs_to` A versioned model but references a specific version
84
84
 
85
- `belongs_to` must specify the `foreign_key` and primary key settings. You should set autosave to false on the `belongs_to` for these types
86
- of associations.
85
+ `belongs_to` must specify the `foreign_key` and primary key settings.
87
86
 
88
87
  class Contract < ActiveRecord::Base
89
88
  include VersionedRecord
90
89
  has_many :apprentices, {
91
- foreign_key: [:contract_id, :contract_version],
92
- primary_key: [:id, :version ]
90
+ foreign_key: [:contract_id, :contract_version]
93
91
  }
94
92
  end
95
93
 
96
94
  class Apprentice < ActiveRecord::Base
97
95
  belongs_to :contract, {
98
- foreign_key: [:contract_id, :contract_version],
99
- primary_key: [ :id, version ],
100
- autosave: false
96
+ foreign_key: [:contract_id, :contract_version]
101
97
  }
102
98
  end
103
99
 
@@ -1,3 +1,3 @@
1
1
  module VersionedRecord
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -70,7 +70,8 @@ module VersionedRecord
70
70
  def build_version(new_attrs = {})
71
71
  new_version = self.class.new(new_version_attrs(new_attrs)).tap do |built|
72
72
  built.deprecate_old_versions_after_create!
73
- end
73
+ preserve_has_one_associations_to(built)
74
+ end
74
75
  end
75
76
 
76
77
  # Retrieve all versions of this record
@@ -124,5 +125,26 @@ module VersionedRecord
124
125
  deprecate_old_versions(self)
125
126
  end
126
127
  end
128
+
129
+ # This is required because a new version which has not been persisted
130
+ # to the database breaks the normal ActiveRecord paradigm.
131
+ # Because normally when a record has not yet been persisted
132
+ # it can have no persisted has_one associations because there is no foriegn key.
133
+ # In our case we have a foreign key because it was determined from the
134
+ # previous version.
135
+ #
136
+ # This doesn't apply to composite has_one associations because they will
137
+ # use a different foreign key to the parent version.
138
+ #
139
+ def preserve_has_one_associations_to(new_version)
140
+ # Preserve simple has_one reflections
141
+ self.class.reflections.select { |_, reflection|
142
+ reflection.macro == :has_one
143
+ }.each do |key, reflection|
144
+ if !reflection.foreign_key.kind_of?(Array)
145
+ new_version.send("#{key}=", self.send(key))
146
+ end
147
+ end
148
+ end
127
149
  end
128
150
  end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe VersionedProduct do
4
+ # TODO: This might be a sep spec as well!
5
+ describe 'preservation across versioning' do
6
+ let(:installation) { Installation.create(installed_by: 'Sean Connery') }
7
+ let(:container) { Container.create(name: 'A Container') }
8
+
9
+ let!(:versioned_product) do
10
+ VersionedProduct.create(
11
+ name: 'iPad',
12
+ price: 100,
13
+ installation: installation,
14
+ container: container
15
+ )
16
+ end
17
+
18
+ let!(:comment) { versioned_product.comments.create(content: 'Foo') }
19
+
20
+ specify 'the versioned product has its associations set' do
21
+ versioned_product.reload
22
+ expect(versioned_product.installation).to eq(installation)
23
+ expect(versioned_product.container).to eq(container)
24
+ expect(versioned_product).to have(1).comment
25
+ end
26
+
27
+ describe 'build a new version of the product' do
28
+ let(:new_version) { versioned_product.build_version }
29
+
30
+ specify 'that the installation is still set' do
31
+ expect(new_version.installation).to eq(installation)
32
+ end
33
+
34
+ specify 'that the container is NOT set (because its a composite relationship)' do
35
+ expect(new_version.container).to be_nil
36
+ end
37
+
38
+ specify 'thet the comments are still set' do
39
+ expect(new_version.comments).to include(comment)
40
+ expect(new_version).to have(1).comment
41
+ end
42
+ end
43
+
44
+ describe 'create a new version of the product' do
45
+ let(:new_version) { versioned_product.create_version }
46
+
47
+ specify 'that the installation is still set' do
48
+ expect(new_version.installation).to eq(installation)
49
+ end
50
+
51
+ specify 'thet the comments are still set' do
52
+ expect(new_version.comments).to include(comment)
53
+ expect(new_version).to have(1).comment
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe VersionedProduct do
4
+ describe 'installation' do
5
+ let!(:versioned_product) { VersionedProduct.create(name: 'iPad', price: 100) }
6
+ let!(:versioned_product_revision) { versioned_product.create_version!(name: 'iPad 2') }
7
+
8
+ describe 'creation via association' do
9
+ let!(:installation) { versioned_product.create_installation!(installed_by: 'Roger Moore') }
10
+
11
+ specify 'that the installation belongs to the latest version' do
12
+ expect(installation.versioned_product).to eq(versioned_product_revision)
13
+ end
14
+
15
+ specify 'that the latest version of the product has the installation set after reload' do
16
+ expect(versioned_product_revision.reload.installation).to eq(installation)
17
+ end
18
+
19
+ specify 'that the previous version of the product has the installation set after reload' do
20
+ expect(versioned_product.reload.installation).to eq(installation)
21
+ end
22
+ end
23
+
24
+ describe 'direct creation' do
25
+ let(:installation) { Installation.new(installed_by: 'Sean Connery') }
26
+ subject { VersionedProduct.create(name: 'iPad', price: 100, installation: installation) }
27
+
28
+ specify 'that the installation is set and persisted' do
29
+ expect(subject.reload.installation).to eq(installation)
30
+ end
31
+ end
32
+
33
+ describe 'simple test' do
34
+ let(:installation) { Installation.new(installed_by: 'Sean Connery') }
35
+ subject { Office.create(address: 'CQ Sydney', installation: installation) }
36
+
37
+ specify 'that the installation is set and persisted' do
38
+ expect(subject.reload.installation).to eq(installation)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -4,44 +4,6 @@ describe VersionedProduct do
4
4
  let!(:versioned_product) { VersionedProduct.create(name: 'iPad', price: 100) }
5
5
  let!(:versioned_product_revision) { versioned_product.create_version!(name: 'iPad 2') }
6
6
 
7
- # TODO: This maybe should go into a different spec
8
- describe 'installation' do
9
- describe 'creation via association' do
10
- let!(:installation) { versioned_product.create_installation!(installed_by: 'Roger Moore') }
11
-
12
- specify 'that the installation belongs to the latest version' do
13
- expect(installation.versioned_product).to eq(versioned_product_revision)
14
- end
15
-
16
- specify 'that the latest version of the product has the installation set after reload' do
17
- expect(versioned_product_revision.reload.installation).to eq(installation)
18
- end
19
-
20
- specify 'that the previous version of the product has the installation set after reload' do
21
- expect(versioned_product.reload.installation).to eq(installation)
22
- end
23
- end
24
-
25
- describe 'direct creation' do
26
- let(:installation) { Installation.new(installed_by: 'Sean Connery') }
27
- subject { VersionedProduct.create(name: 'iPad', price: 100, installation: installation) }
28
-
29
- specify 'that the installation is set and persisted' do
30
- expect(subject.reload.installation).to eq(installation)
31
- end
32
- end
33
-
34
- describe 'simple test' do
35
- let(:installation) { Installation.new(installed_by: 'Sean Connery') }
36
- subject { Office.create(address: 'CQ Sydney', installation: installation) }
37
-
38
- specify 'that the installation is set and persisted' do
39
- expect(subject.reload.installation).to eq(installation)
40
- end
41
-
42
- end
43
- end
44
-
45
7
  describe 'office' do
46
8
  describe 'creation via association' do
47
9
  let!(:office) { Office.create!(address: 'Circular Quay, Sydney') }
@@ -0,0 +1,7 @@
1
+ class Container < ActiveRecord::Base
2
+ include VersionedRecord
3
+
4
+ belongs_to :versioned_product, {
5
+ foreign_key: [:versioned_product_id, :versioned_product_version],
6
+ }
7
+ end
@@ -50,4 +50,10 @@ ActiveRecord::Schema.define :version => 0 do
50
50
  create_table :offices, force: true do |t|
51
51
  t.string :address
52
52
  end
53
+
54
+ create_table :containers, versioned: true, force: true do |t|
55
+ t.references :versioned_product
56
+ t.integer :versioned_product_version
57
+ t.string :name
58
+ end
53
59
  end
data/spec/support/sale.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  class Sale < ActiveRecord::Base
2
2
  belongs_to :versioned_product, {
3
3
  foreign_key: [:versioned_product_id, :versioned_product_version],
4
- primary_key: [:id, :version ],
5
- autosave: false
4
+ autosave: true
6
5
  }
7
6
  end
@@ -8,10 +8,9 @@ class VersionedProduct < ActiveRecord::Base
8
8
  # Simple Belongs To
9
9
  has_many :comments
10
10
 
11
- # Composite Belongs To
11
+ # Composite has many
12
12
  has_many :sales, {
13
- foreign_key: [:versioned_product_id, :versioned_product_version],
14
- primary_key: [:id, :version ]
13
+ foreign_key: [:versioned_product_id, :versioned_product_version]
15
14
  }
16
15
 
17
16
  # Simple HABTM
@@ -29,4 +28,9 @@ class VersionedProduct < ActiveRecord::Base
29
28
  # Has one and has one through
30
29
  has_one :installation
31
30
  has_one :office, through: :installation
31
+
32
+ # Composite has_one
33
+ has_one :container, {
34
+ foreign_key: [:versioned_product_id, :versioned_product_version]
35
+ }
32
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: versioned_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Draper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-21 00:00:00.000000000 Z
11
+ date: 2014-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -174,14 +174,17 @@ files:
174
174
  - lib/versioned_record/composite_predicates.rb
175
175
  - lib/versioned_record/connection_adapters/postgresql.rb
176
176
  - lib/versioned_record/version.rb
177
+ - spec/association_preservation_spec.rb
177
178
  - spec/composite_belongs_to.rb
178
179
  - spec/composite_onesided_habtm_spec.rb
180
+ - spec/has_one_spec.rb
179
181
  - spec/has_one_through_spec.rb
180
182
  - spec/simple_belongs_to_spec.rb
181
183
  - spec/simple_onesided_habtm_spec.rb
182
184
  - spec/spec_helper.rb
183
185
  - spec/support/comment.rb
184
186
  - spec/support/company.rb
187
+ - spec/support/container.rb
185
188
  - spec/support/database.rb
186
189
  - spec/support/database.yml
187
190
  - spec/support/installation.rb
@@ -218,14 +221,17 @@ signing_key:
218
221
  specification_version: 4
219
222
  summary: Version ActiveRecord models using composite primary keys
220
223
  test_files:
224
+ - spec/association_preservation_spec.rb
221
225
  - spec/composite_belongs_to.rb
222
226
  - spec/composite_onesided_habtm_spec.rb
227
+ - spec/has_one_spec.rb
223
228
  - spec/has_one_through_spec.rb
224
229
  - spec/simple_belongs_to_spec.rb
225
230
  - spec/simple_onesided_habtm_spec.rb
226
231
  - spec/spec_helper.rb
227
232
  - spec/support/comment.rb
228
233
  - spec/support/company.rb
234
+ - spec/support/container.rb
229
235
  - spec/support/database.rb
230
236
  - spec/support/database.yml
231
237
  - spec/support/installation.rb