deferring 0.2.1 → 0.3.0
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 +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +16 -15
- data/Appraisals +8 -8
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/deferring.gemspec +1 -1
- data/gemfiles/rails_40.gemfile +1 -1
- data/gemfiles/rails_40.gemfile.lock +34 -30
- data/gemfiles/rails_41.gemfile +1 -1
- data/gemfiles/rails_41.gemfile.lock +35 -31
- data/gemfiles/{rails_30.gemfile → rails_42.gemfile} +1 -1
- data/gemfiles/rails_42.gemfile.lock +64 -0
- data/gemfiles/{rails_32.gemfile → rails_50.gemfile} +1 -1
- data/gemfiles/rails_50.gemfile.lock +63 -0
- data/lib/deferring.rb +55 -52
- data/lib/deferring/deferred_association.rb +8 -6
- data/lib/deferring/deferred_callback_listener.rb +9 -3
- data/lib/deferring/version.rb +1 -3
- data/spec/lib/deferring_habtm_spec.rb +140 -90
- data/spec/lib/deferring_has_many_spec.rb +58 -44
- data/spec/spec_helper.rb +12 -1
- data/spec/support/active_record.rb +5 -5
- metadata +10 -11
- data/gemfiles/rails_30.gemfile.lock +0 -55
- data/gemfiles/rails_32.gemfile.lock +0 -57
- data/spec/support/rails_versions.rb +0 -13
@@ -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
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
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
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
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
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
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.
|
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:
|
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: '
|
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: '
|
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.
|
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
|
-
|
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
|