HornsAndHooves-moribus 0.7.2 → 0.9.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
  SHA256:
3
- metadata.gz: 030306473aaa6548bb98b95cce958cc4861fbf923ac99e33df4c31c5e5e54298
4
- data.tar.gz: 8fa274a49fd8f7aaefdb30fb388281c089c0029fb0d861299ca760d5544d3ed8
3
+ metadata.gz: 54e52262da75d0c70f93a440dab8adbebc1c9ccb23d8bf9eff905572ca9028ae
4
+ data.tar.gz: a4c982838e5ea190585f1e8d8bfe776574584bb669136f372506fec7d9e5e38e
5
5
  SHA512:
6
- metadata.gz: e541ea1a31728d2156e52602601abb8a1e24181b7dcd90a0799e6a588cc78e48e2ba7833e236ca7a4230ac8fc29ea50e741e2914adaedb8f21291f4e924c6929
7
- data.tar.gz: 0e744f9a43ac59e002928c05fe12c8ee69d06245733ad85d7417042ccf1d1a544a9c56f0b40cfad97d48e4f7476cefdb5c1d6e742b6edf14aeebf2f50c7ca473
6
+ metadata.gz: 7b1bbadc5517c5309af3dd7f8dcc358e9966f5c7ef0ba6bbf3ee47b466d1771ab27620a3204ac45635bcd71f9619e16010eb5559d3b651adc951663cadeec101
7
+ data.tar.gz: 268eab60e758cc9f5f4dee5c44d8d60dfc6b5ec0f471d7108b73ba1bafe62b963b09724929fa3e65b5a07a400f9024545cb9a26bbc626ba944d1d4a75f65fa22
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.4.6
1
+ 2.6.6
@@ -20,12 +20,12 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  # specify any dependencies here; for example:
23
- s.add_dependency "rails", "~> 5"
23
+ s.add_dependency "rails", "~> 6"
24
24
  s.add_dependency "power_enum", ">= 2.7.0"
25
25
  s.add_dependency "yard", ">= 0"
26
26
 
27
27
  s.add_development_dependency "rake"
28
28
  s.add_development_dependency "rspec"
29
29
  s.add_development_dependency "rspec-rails"
30
- s.add_development_dependency "sqlite3", "~> 1.3.6"
30
+ s.add_development_dependency "sqlite3"
31
31
  end
@@ -31,7 +31,7 @@ module Moribus
31
31
  class_attribute :aggregated_records_cache
32
32
  self.aggregated_records_cache = {}
33
33
 
34
- after_save :cache_aggregated_record, :on => :create
34
+ after_save :cache_aggregated_record
35
35
  end
36
36
 
37
37
  # Class methods for model that includes AggregatedCacheBehavior
@@ -45,7 +45,7 @@ module Moribus
45
45
  options = scope if scope.is_a?(Hash)
46
46
 
47
47
  alias_name = options.delete(:alias)
48
- reflection = super(name, scope, options, &extension)
48
+ reflection = super(name, scope, **options, &extension)
49
49
  alias_association(alias_name, name) if alias_name
50
50
  reflection
51
51
  end
@@ -55,7 +55,7 @@ module Moribus
55
55
  options = scope if scope.is_a?(Hash)
56
56
 
57
57
  alias_name = options.delete(:alias)
58
- reflection = super(name, scope, options)
58
+ reflection = super(name, scope, **options)
59
59
  alias_association(alias_name, name) if alias_name
60
60
  reflection
61
61
  end
@@ -6,21 +6,32 @@ module Moribus
6
6
  # Sets 'is_current' flag of overridden record to false, instead
7
7
  # of deleting it or setting foreign key to nil.
8
8
  def remove_target!(*)
9
+ # Use custom update to avoid running ActiveRecord optimistic locking
10
+ # and to avoid updating lock_version column:
9
11
  if target.new_record?
10
12
  target.is_current = false
13
+ target.updated_at = Time.zone.now if has_updated_at_column?
11
14
  else
12
- # Use custom update to avoid running ActiveRecord optimistic locking
13
- # and to avoid updating lock_version column:
14
15
  klass = target.class
15
16
 
16
17
  sql = "UPDATE #{klass.quoted_table_name} " \
17
18
  "SET \"is_current\" = #{klass.connection.quote(false)} "
19
+
20
+ sql << %{, "updated_at" = #{klass.connection.quote(Time.zone.now)} } if has_updated_at_column?
21
+
18
22
  sql << "WHERE #{klass.quoted_primary_key} = " \
19
23
  "#{klass.connection.quote(target.send(klass.primary_key))} "
20
24
 
21
25
  klass.connection.update sql
22
26
  end
23
27
  end
28
+
29
+ # Is the record has a column with name `updated_at`
30
+ #
31
+ # @return [Boolean]
32
+ private def has_updated_at_column?
33
+ target.class.column_names.include?("updated_at")
34
+ end
24
35
  end
25
36
  end
26
37
  end
@@ -91,7 +91,7 @@ module Moribus
91
91
  scope = current_scope
92
92
  end
93
93
 
94
- reflection = has_one(name, scope, options)
94
+ reflection = has_one(name, scope, **options)
95
95
  reflection = normalize_reflection(reflection, name)
96
96
  reflection.options[:is_current] = true
97
97
  accepts_nested_attributes_for name
@@ -106,7 +106,7 @@ module Moribus
106
106
  # by special aggregated functionality (attribute delegation. See
107
107
  # Extensions::HasAggregatedExtension)
108
108
  def has_aggregated(name, options = {})
109
- reflection = belongs_to(name, options)
109
+ reflection = belongs_to(name, **options)
110
110
  reflection = normalize_reflection(reflection, name)
111
111
  reflection.options[:aggregated] = true
112
112
  accepts_nested_attributes_for name
@@ -1,3 +1,3 @@
1
1
  module Moribus # :nodoc:
2
- VERSION = "0.7.2" # :nodoc:
2
+ VERSION = "0.9.1" # :nodoc:
3
3
  end
@@ -0,0 +1,5 @@
1
+ // Sprockets 4.0+ requires this file to define asset paths.
2
+
3
+ //= link_tree ../images
4
+ //= link_directory ../javascripts .js
5
+ //= link_directory ../stylesheets .css
@@ -93,7 +93,7 @@ describe Moribus::AggregatedBehavior do
93
93
 
94
94
  it "looks up self and replaces id with existing on update" do
95
95
  name = SpecPersonName.create first_name: "Alice", last_name: "Smith"
96
- name.update_attributes first_name: "John"
96
+ name.update! first_name: "John"
97
97
  expect(name.id).to eq @existing.id
98
98
  end
99
99
 
@@ -16,6 +16,7 @@ describe Moribus::Extensions::HasCurrentExtension do
16
16
 
17
17
  class SpecCustomer < MoribusSpecModel(spec_status_id: :integer)
18
18
  has_one_current :spec_customer_info, inverse_of: :spec_customer, dependent: :destroy
19
+ delegate_associated :previous_id, to: :spec_customer_info
19
20
  end
20
21
  end
21
22
 
@@ -24,17 +25,45 @@ describe Moribus::Extensions::HasCurrentExtension do
24
25
  end
25
26
 
26
27
  let(:customer) { SpecCustomer.create }
27
- let!(:info) { SpecCustomerInfo.create(spec_customer: customer, is_current: true) }
28
+ let!(:info) do
29
+ SpecCustomerInfo.create(spec_customer: customer, is_current: true, created_at: 1.hour.ago, updated_at: 1.hour.ago)
30
+ end
28
31
 
29
32
  describe ".remove_target!" do
30
- before do
31
- allow(customer.spec_customer_info).to receive(:new_record?).and_return(true)
33
+ context "new record" do
34
+ before do
35
+ allow(customer.spec_customer_info).to receive(:new_record?).and_return(true)
36
+ end
37
+
38
+ it "sets 'is_current' flag of overridden record to false for new record" do
39
+ old_info = customer.spec_customer_info
40
+ customer.spec_customer_info = SpecCustomerInfo.new
41
+ expect(old_info.is_current).to be false
42
+ end
43
+
44
+ it "sets 'is_current' flag updates updated_at column" do
45
+ old_info = customer.spec_customer_info
46
+ customer.spec_customer_info = SpecCustomerInfo.new
47
+ expect(old_info.updated_at >= old_info.created_at + 1.hour).to be true
48
+ end
32
49
  end
33
50
 
34
- it "sets 'is_current' flag of overridden record to false for new record" do
35
- old_info = customer.spec_customer_info
36
- customer.spec_customer_info = SpecCustomerInfo.new
37
- expect(old_info.is_current).to be_falsey
51
+ context "persisted record" do
52
+ it "sets 'is_current' flag updates updated_at column" do
53
+ old_info = customer.spec_customer_info
54
+ customer.spec_customer_info = SpecCustomerInfo.new
55
+ old_info.reload
56
+ # I use 59 minutes instead of hour because there can be small difference in milliseconds
57
+ expect(old_info.updated_at >= old_info.created_at + 59.minutes).to be true
58
+ end
59
+
60
+ it "sets 'is_current' flag updates updated_at column" do
61
+ old_info = customer.spec_customer_info
62
+ customer.update!(previous_id: 123)
63
+ old_info.reload
64
+ # I use 59 minutes instead of hour because there can be small difference in milliseconds
65
+ expect(old_info.updated_at >= old_info.created_at + 59.minutes).to be true
66
+ end
38
67
  end
39
68
  end
40
69
  end
data/spec/moribus_spec.rb CHANGED
@@ -128,7 +128,7 @@ describe Moribus do
128
128
 
129
129
  suppress(Exception) do
130
130
  expect {
131
- @info.update_attributes spec_customer_id: nil, spec_person_name_id: 2
131
+ @info.update! spec_customer_id: nil, spec_person_name_id: 2
132
132
  }.not_to change(SpecCustomerInfo, :count)
133
133
  end
134
134
 
@@ -155,25 +155,25 @@ describe Moribus do
155
155
 
156
156
  it "creates a new current record if updated" do
157
157
  expect {
158
- @info.update_attributes(spec_person_name_id: 2)
158
+ @info.update!(spec_person_name_id: 2)
159
159
  }.to change(SpecCustomerInfo, :count).by(1)
160
160
  end
161
161
 
162
162
  it "replaces itself with new id" do
163
163
  old_id = @info.id
164
- @info.update_attributes(spec_person_name_id: 2)
164
+ @info.update!(spec_person_name_id: 2)
165
165
  expect(@info.id).not_to eq old_id
166
166
  end
167
167
 
168
168
  it "sets is_current record to false for superseded record" do
169
169
  old_id = @info.id
170
- @info.update_attributes(spec_person_name_id: 2)
170
+ @info.update!(spec_person_name_id: 2)
171
171
  expect(SpecCustomerInfo.find(old_id).is_current).to eq false
172
172
  end
173
173
 
174
174
  it "sets previous_id to the id of the previous record" do
175
175
  old_id = @info.id
176
- @info.update_attributes(spec_person_name_id: 2)
176
+ @info.update!(spec_person_name_id: 2)
177
177
  expect(@info.previous_id).to eq old_id
178
178
  end
179
179
 
@@ -191,7 +191,7 @@ describe Moribus do
191
191
  status: "unverified",
192
192
  is_current: true
193
193
  )
194
- expect{ email.update_attributes(status: "verified") }.not_to raise_error
194
+ expect{ email.update!(status: "verified") }.not_to raise_error
195
195
  end
196
196
 
197
197
  describe "updated_at and created_at" do
@@ -221,9 +221,9 @@ describe Moribus do
221
221
  end
222
222
 
223
223
  it "raises a stale object error" do
224
- @info1.update_attributes(spec_person_name_id: 3)
224
+ @info1.update!(spec_person_name_id: 3)
225
225
 
226
- expect{ @info2.update_attributes(spec_person_name_id: 4) }.
226
+ expect{ @info2.update!(spec_person_name_id: 4) }.
227
227
  to raise_error(ActiveRecord::StaleObjectError,
228
228
  /Attempted to update_current \(version #{@info2.lock_version}\) a stale object: SpecCustomerInfo\./)
229
229
  end
@@ -232,30 +232,30 @@ describe Moribus do
232
232
  spec_customer_info = @customer.spec_customer_info
233
233
 
234
234
  expect {
235
- spec_customer_info.update_attributes(spec_person_name_id: 3)
235
+ spec_customer_info.update!(spec_person_name_id: 3)
236
236
  }.to change { spec_customer_info.lock_version }.from(0).to(1)
237
237
 
238
238
  expect {
239
- spec_customer_info.update_attributes(spec_person_name_id: 4)
239
+ spec_customer_info.update!(spec_person_name_id: 4)
240
240
  }.to change { spec_customer_info.lock_version }.from(1).to(2)
241
241
  end
242
242
 
243
243
  it "does not fail to update if a lock version growth is for any reason not monotonic" do
244
244
  spec_customer_info = @customer.spec_customer_info
245
245
 
246
- spec_customer_info.update_attributes(spec_person_name_id: 3)
247
- spec_customer_info.update_attributes(spec_person_name_id: 4)
246
+ spec_customer_info.update!(spec_person_name_id: 3)
247
+ spec_customer_info.update!(spec_person_name_id: 4)
248
248
 
249
249
  SpecCustomerInfo.where(spec_customer_id: @customer.id, lock_version: 1).delete_all
250
250
 
251
251
  expect {
252
- spec_customer_info.update_attributes(spec_person_name_id: 5)
252
+ spec_customer_info.update!(spec_person_name_id: 5)
253
253
  }.to change { spec_customer_info.lock_version }.from(2).to(3)
254
254
  end
255
255
 
256
256
  it "does not fail if no locking_column is present" do
257
257
  email = SpecCustomerEmail.create(spec_customer_id: 1, email: "foo@bar.com")
258
- expect{ email.update_attributes(email: "foo2@bar.com") }.not_to raise_error
258
+ expect{ email.update!(email: "foo2@bar.com") }.not_to raise_error
259
259
  end
260
260
 
261
261
  it "updates lock_version column based on parent relation" do
@@ -263,11 +263,11 @@ describe Moribus do
263
263
  spec_customer_info = @customer.spec_customer_info
264
264
 
265
265
  expect {
266
- spec_customer_info.update_attributes(spec_person_name_id: 3)
266
+ spec_customer_info.update!(spec_person_name_id: 3)
267
267
  }.to change { spec_customer_info.lock_version }.from(0).to(1)
268
268
 
269
269
  expect {
270
- spec_customer_info.update_attributes(spec_customer: @other_customer)
270
+ spec_customer_info.update!(spec_customer: @other_customer)
271
271
  }.to change { spec_customer_info.lock_version }.from(1).to(0)
272
272
  end
273
273
 
@@ -282,10 +282,10 @@ describe Moribus do
282
282
 
283
283
  expect( other_info_with_type.lock_version ).to eq 0
284
284
 
285
- info_with_type.update_attributes(spec_status: :active)
285
+ info_with_type.update!(spec_status: :active)
286
286
  expect( info_with_type.lock_version ).to eq 1
287
287
 
288
- info_with_type.update_attributes(spec_status: :inactive)
288
+ info_with_type.update!(spec_status: :inactive)
289
289
  expect( info_with_type.lock_version ).to eq 2
290
290
 
291
291
  expect( other_info_with_type.lock_version ).to eq 0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: HornsAndHooves-moribus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - HornsAndHooves
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2021-03-11 00:00:00.000000000 Z
14
+ date: 2022-08-24 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rails
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - "~>"
21
21
  - !ruby/object:Gem::Version
22
- version: '5'
22
+ version: '6'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '5'
29
+ version: '6'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: power_enum
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -101,16 +101,16 @@ dependencies:
101
101
  name: sqlite3
102
102
  requirement: !ruby/object:Gem::Requirement
103
103
  requirements:
104
- - - "~>"
104
+ - - ">="
105
105
  - !ruby/object:Gem::Version
106
- version: 1.3.6
106
+ version: '0'
107
107
  type: :development
108
108
  prerelease: false
109
109
  version_requirements: !ruby/object:Gem::Requirement
110
110
  requirements:
111
- - - "~>"
111
+ - - ">="
112
112
  - !ruby/object:Gem::Version
113
- version: 1.3.6
113
+ version: '0'
114
114
  description: |-
115
115
  Introduces Aggregated and Tracked behavior to ActiveRecord::Base models, as well
116
116
  as Macros and Extensions modules for more efficient usage.
@@ -147,6 +147,7 @@ files:
147
147
  - lib/moribus/version.rb
148
148
  - spec/dummy/README.rdoc
149
149
  - spec/dummy/Rakefile
150
+ - spec/dummy/app/assets/config/manifest.js
150
151
  - spec/dummy/app/assets/javascripts/application.js
151
152
  - spec/dummy/app/assets/stylesheets/application.css
152
153
  - spec/dummy/app/controllers/application_controller.rb
@@ -207,14 +208,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
208
  - !ruby/object:Gem::Version
208
209
  version: '0'
209
210
  requirements: []
210
- rubyforge_project:
211
- rubygems_version: 2.7.9
211
+ rubygems_version: 3.0.8
212
212
  signing_key:
213
213
  specification_version: 4
214
214
  summary: Introduces Aggregated and Tracked behavior to ActiveRecord::Base models
215
215
  test_files:
216
216
  - spec/dummy/README.rdoc
217
217
  - spec/dummy/Rakefile
218
+ - spec/dummy/app/assets/config/manifest.js
218
219
  - spec/dummy/app/assets/javascripts/application.js
219
220
  - spec/dummy/app/assets/stylesheets/application.css
220
221
  - spec/dummy/app/controllers/application_controller.rb