versioned_record 0.3.0 → 0.3.1

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.
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