deferring 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -63,6 +63,33 @@ RSpec.describe 'deferred has_many associations' do
63
63
  expect(bob.issues).to be_empty
64
64
  end
65
65
 
66
+ describe '#changed_for_autosave?' do
67
+ it 'returns true if there is a pending create' do
68
+ bob.issues = [printer_issue]
69
+ changed, queries = catch_queries { bob.changed_for_autosave? }
70
+ expect(queries).to be_empty
71
+ expect(changed).to eq(true)
72
+ end
73
+
74
+ it 'returns true if there is a pending delete' do
75
+ bob.issues = [printer_issue]
76
+ bob.save!
77
+
78
+ bob = Person.where(name: 'Bob').first
79
+ bob.issues.delete(printer_issue)
80
+ changed, queries = catch_queries { bob.changed_for_autosave? }
81
+ expect(queries).to be_empty
82
+ expect(changed).to eq(true)
83
+ end
84
+
85
+ it 'does not perform any queries if the original association has not been loaded' do
86
+ bob.issues = [printer_issue]
87
+ changed, queries = catch_queries { bob.changed_for_autosave? }
88
+ expect(queries).to be_empty
89
+ expect(changed).to eq(true)
90
+ end
91
+ end
92
+
66
93
  describe 'validations' do
67
94
  xit 'does not create a link when parent is not valid'
68
95
 
@@ -120,26 +147,24 @@ RSpec.describe 'deferred has_many associations' do
120
147
  expect(bob.non_validated_issues.first.validation_log).to eq([])
121
148
  end
122
149
 
123
- unless rails30 # rails 3.0 does not return a error
124
- it 'fails when trying to save the parent' do
125
- bob.non_validated_issues = [NonValidatedIssue.new]
126
-
127
- # Rails will raise the following error:
128
- # - ActiveRecord::RecordNotSaved:
129
- # Failed to replace non_validated_issues because one or more of the new records could not be saved.
130
- #
131
- # This behaviour is different from the default Rails behaviour.
132
- # Rails will normally just save the parent and not save the
133
- # association.
134
- #
135
- # Two ways to avoid this error (using the Deferring gem):
136
- # - always use validate: true when user input is involved (e.g.
137
- # using nested attributes to update the association),
138
- # - add validations to the parent to check validness of the
139
- # children when a child record can be valid on itself but invalid
140
- # when added to the parent
141
- expect{ bob.save }.to raise_error
142
- end
150
+ it 'fails when trying to save the parent' do
151
+ bob.non_validated_issues = [NonValidatedIssue.new]
152
+
153
+ # Rails will raise the following error:
154
+ # - ActiveRecord::RecordNotSaved:
155
+ # Failed to replace non_validated_issues because one or more of the new records could not be saved.
156
+ #
157
+ # This behaviour is different from the default Rails behaviour.
158
+ # Rails will normally just save the parent and not save the
159
+ # association.
160
+ #
161
+ # Two ways to avoid this error (using the Deferring gem):
162
+ # - always use validate: true when user input is involved (e.g.
163
+ # using nested attributes to update the association),
164
+ # - add validations to the parent to check validness of the
165
+ # children when a child record can be valid on itself but invalid
166
+ # when added to the parent
167
+ expect{ bob.save }.to raise_error(ActiveRecord::RecordNotSaved)
143
168
  end
144
169
  end
145
170
 
@@ -312,33 +337,22 @@ RSpec.describe 'deferred has_many associations' do
312
337
  bob.save!
313
338
  end
314
339
 
315
- if rails30 # old-style preload
316
- it 'should have loaded the association' do
317
- bob = Person.where(name: 'Bob').first
318
- Person.send(:preload_associations, bob, [:issues])
319
- expect(bob.issues.loaded?).to be_truthy
320
- expect(bob.issue_ids).to eq [printer_issue.id, db_issue.id]
321
- end
340
+ it 'should have loaded the association when pre-loading' do
341
+ people = Person.preload(:issues)
342
+ expect(people[1].issues.loaded?).to be_truthy
343
+ expect(people[1].issue_ids).to eq [printer_issue.id, db_issue.id]
322
344
  end
323
345
 
324
- if rails32 || rails4
325
- it 'should have loaded the association when pre-loading' do
326
- people = Person.preload(:issues)
327
- expect(people[1].issues.loaded?).to be_truthy
328
- expect(people[1].issue_ids).to eq [printer_issue.id, db_issue.id]
329
- end
330
-
331
- it 'should have loaded the association when eager loading' do
332
- people = Person.eager_load(:issues)
333
- expect(people[1].issues.loaded?).to be_truthy
334
- expect(people[1].issue_ids).to eq [db_issue.id, printer_issue.id]
335
- end
346
+ it 'should have loaded the association when eager loading' do
347
+ people = Person.eager_load(:issues)
348
+ expect(people[1].issues.loaded?).to be_truthy
349
+ expect(people[1].issue_ids).to eq [db_issue.id, printer_issue.id]
350
+ end
336
351
 
337
- it 'should have loaded the association when joining' do
338
- people = Person.includes(:issues).to_a
339
- expect(people[1].issues.loaded?).to be_truthy
340
- expect(people[1].issue_ids).to eq [printer_issue.id, db_issue.id]
341
- end
352
+ it 'should have loaded the association when joining' do
353
+ people = Person.includes(:issues).to_a
354
+ expect(people[1].issues.loaded?).to be_truthy
355
+ expect(people[1].issue_ids).to eq [printer_issue.id, db_issue.id]
342
356
  end
343
357
 
344
358
  it 'should not have loaded the association when using a regular query' do
data/spec/spec_helper.rb CHANGED
@@ -5,7 +5,6 @@ require 'support/models/team'
5
5
  require 'support/models/issue'
6
6
  require 'support/models/address'
7
7
  require 'support/models/non_validated_issue'
8
- require 'support/rails_versions'
9
8
 
10
9
  RSpec.configure do |config|
11
10
  config.disable_monkey_patching!
@@ -27,5 +26,17 @@ RSpec.configure do |config|
27
26
  raise ActiveRecord::Rollback
28
27
  end
29
28
  end
29
+ end
30
+
31
+ # Catch queries executed within the &block
32
+ def catch_queries(&block)
33
+ queries = []
34
+ callback = lambda { |name, start, finish, id, payload|
35
+ queries << payload[:sql] if payload[:sql] =~ /^SELECT|UPDATE|INSERT/
36
+ }
30
37
 
38
+ result = ActiveSupport::Notifications.subscribed(callback, 'sql.active_record') do
39
+ yield
40
+ end
41
+ [result, queries]
31
42
  end
@@ -6,7 +6,7 @@ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
6
6
  ActiveRecord::Schema.define version: 0 do
7
7
  create_table :people do |t|
8
8
  t.string :name
9
- t.timestamps
9
+ t.timestamps null: false
10
10
  end
11
11
 
12
12
  create_table :people_teams, id: false do |t|
@@ -16,26 +16,26 @@ ActiveRecord::Schema.define version: 0 do
16
16
 
17
17
  create_table :teams do |t|
18
18
  t.string :name
19
- t.timestamps
19
+ t.timestamps null: false
20
20
  end
21
21
 
22
22
  create_table :issues do |t|
23
23
  t.string :subject
24
24
  t.integer :person_id
25
- t.timestamps
25
+ t.timestamps null: false
26
26
  end
27
27
 
28
28
  create_table :addresses do |t|
29
29
  t.integer :addressable_id
30
30
  t.string :addressable_type
31
31
  t.string :street
32
- t.timestamps
32
+ t.timestamps null: false
33
33
  end
34
34
 
35
35
  create_table :non_validated_issues do |t|
36
36
  t.string :subject
37
37
  t.integer :person_id
38
- t.timestamps
38
+ t.timestamps null: false
39
39
  end
40
40
  end
41
41
  ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deferring
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robin Roestenburg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-06 00:00:00.000000000 Z
11
+ date: 2017-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '4.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">"
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '4.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -111,14 +111,14 @@ files:
111
111
  - README.md
112
112
  - Rakefile
113
113
  - deferring.gemspec
114
- - gemfiles/rails_30.gemfile
115
- - gemfiles/rails_30.gemfile.lock
116
- - gemfiles/rails_32.gemfile
117
- - gemfiles/rails_32.gemfile.lock
118
114
  - gemfiles/rails_40.gemfile
119
115
  - gemfiles/rails_40.gemfile.lock
120
116
  - gemfiles/rails_41.gemfile
121
117
  - gemfiles/rails_41.gemfile.lock
118
+ - gemfiles/rails_42.gemfile
119
+ - gemfiles/rails_42.gemfile.lock
120
+ - gemfiles/rails_50.gemfile
121
+ - gemfiles/rails_50.gemfile.lock
122
122
  - lib/deferring.rb
123
123
  - lib/deferring/deferred_association.rb
124
124
  - lib/deferring/deferred_callback_listener.rb
@@ -133,7 +133,6 @@ files:
133
133
  - spec/support/models/non_validated_issue.rb
134
134
  - spec/support/models/person.rb
135
135
  - spec/support/models/team.rb
136
- - spec/support/rails_versions.rb
137
136
  homepage: http://github.com/robinroestenburg/deferring
138
137
  licenses:
139
138
  - MIT
@@ -154,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
153
  version: '0'
155
154
  requirements: []
156
155
  rubyforge_project:
157
- rubygems_version: 2.2.2
156
+ rubygems_version: 2.5.1
158
157
  signing_key:
159
158
  specification_version: 4
160
159
  summary: Defer saving ActiveRecord associations until parent is saved
@@ -169,4 +168,4 @@ test_files:
169
168
  - spec/support/models/non_validated_issue.rb
170
169
  - spec/support/models/person.rb
171
170
  - spec/support/models/team.rb
172
- - spec/support/rails_versions.rb
171
+ has_rdoc:
@@ -1,55 +0,0 @@
1
- PATH
2
- remote: ../
3
- specs:
4
- deferring (0.2.0)
5
- activerecord (> 3.0)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activemodel (3.0.19)
11
- activesupport (= 3.0.19)
12
- builder (~> 2.1.2)
13
- i18n (~> 0.5.0)
14
- activerecord (3.0.19)
15
- activemodel (= 3.0.19)
16
- activesupport (= 3.0.19)
17
- arel (~> 2.0.10)
18
- tzinfo (~> 0.3.23)
19
- activesupport (3.0.19)
20
- appraisal (1.0.0)
21
- bundler
22
- rake
23
- thor (>= 0.14.0)
24
- arel (2.0.10)
25
- builder (2.1.2)
26
- diff-lcs (1.2.5)
27
- i18n (0.5.4)
28
- rake (10.3.2)
29
- rspec (3.0.0)
30
- rspec-core (~> 3.0.0)
31
- rspec-expectations (~> 3.0.0)
32
- rspec-mocks (~> 3.0.0)
33
- rspec-core (3.0.0)
34
- rspec-support (~> 3.0.0)
35
- rspec-expectations (3.0.0)
36
- diff-lcs (>= 1.2.0, < 2.0)
37
- rspec-support (~> 3.0.0)
38
- rspec-mocks (3.0.0)
39
- rspec-support (~> 3.0.0)
40
- rspec-support (3.0.0)
41
- sqlite3 (1.3.9)
42
- thor (0.19.1)
43
- tzinfo (0.3.39)
44
-
45
- PLATFORMS
46
- ruby
47
-
48
- DEPENDENCIES
49
- activerecord (= 3.0.19)
50
- appraisal
51
- bundler (~> 1.3)
52
- deferring!
53
- rake
54
- rspec
55
- sqlite3
@@ -1,57 +0,0 @@
1
- PATH
2
- remote: ../
3
- specs:
4
- deferring (0.2.0)
5
- activerecord (> 3.0)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activemodel (3.2.17)
11
- activesupport (= 3.2.17)
12
- builder (~> 3.0.0)
13
- activerecord (3.2.17)
14
- activemodel (= 3.2.17)
15
- activesupport (= 3.2.17)
16
- arel (~> 3.0.2)
17
- tzinfo (~> 0.3.29)
18
- activesupport (3.2.17)
19
- i18n (~> 0.6, >= 0.6.4)
20
- multi_json (~> 1.0)
21
- appraisal (1.0.0)
22
- bundler
23
- rake
24
- thor (>= 0.14.0)
25
- arel (3.0.3)
26
- builder (3.0.4)
27
- diff-lcs (1.2.5)
28
- i18n (0.6.9)
29
- multi_json (1.10.1)
30
- rake (10.3.2)
31
- rspec (3.0.0)
32
- rspec-core (~> 3.0.0)
33
- rspec-expectations (~> 3.0.0)
34
- rspec-mocks (~> 3.0.0)
35
- rspec-core (3.0.0)
36
- rspec-support (~> 3.0.0)
37
- rspec-expectations (3.0.0)
38
- diff-lcs (>= 1.2.0, < 2.0)
39
- rspec-support (~> 3.0.0)
40
- rspec-mocks (3.0.0)
41
- rspec-support (~> 3.0.0)
42
- rspec-support (3.0.0)
43
- sqlite3 (1.3.9)
44
- thor (0.19.1)
45
- tzinfo (0.3.39)
46
-
47
- PLATFORMS
48
- ruby
49
-
50
- DEPENDENCIES
51
- activerecord (= 3.2.17)
52
- appraisal
53
- bundler (~> 1.3)
54
- deferring!
55
- rake
56
- rspec
57
- sqlite3
@@ -1,13 +0,0 @@
1
- def rails30
2
- ActiveRecord::VERSION::MAJOR == 3 &&
3
- ActiveRecord::VERSION::MINOR == 0
4
- end
5
-
6
- def rails32
7
- ActiveRecord::VERSION::MAJOR == 3 &&
8
- ActiveRecord::VERSION::MINOR == 2
9
- end
10
-
11
- def rails4
12
- ActiveRecord::VERSION::MAJOR == 4
13
- end