deferring 0.0.6 → 0.0.7
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 +8 -8
- data/gemfiles/rails_30.gemfile.lock +1 -1
- data/gemfiles/rails_32.gemfile.lock +1 -1
- data/gemfiles/rails_40.gemfile.lock +1 -1
- data/gemfiles/rails_41.gemfile.lock +1 -1
- data/lib/deferring.rb +5 -3
- data/lib/deferring/deferred_association.rb +22 -2
- data/lib/deferring/version.rb +1 -1
- data/spec/lib/deferring_has_many_spec.rb +117 -4
- data/spec/support/models.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YmQ0ODk2NjQ5MWRkMDI2ZjIzZjEyNzdjNzk1MGIyNmVkOGEwNmNjZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MmZmOThmYzFkNDkzOTMzZGNhZmFhYmFkZmViOTc5ZmJmMzZmNjFmYw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OWI3OTAxNjNlNGIzNWZhMGEyMGE5NDM4MzQxODcwMGViZDBmNWNmNDdjZmJl
|
10
|
+
ODY0MzVjNTdhNjU4MjU4ZTQwYzBkNzMwNjU3NWQ2YzA4ZDM2OWU2NThlYTMx
|
11
|
+
NTAwODZjNzYyNGMzNTQ3ZTUxMjlhMzk2NDg5OTIxZjVlMWM3MWE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTEyYzMyNTJiMzBjOTY1ODkwOGE2OWUzZDRkYzNmMGMyYjAyMTE0N2E0Yjg2
|
14
|
+
ZmRjOWNkZjcxZjQxNjQ0Mjc4OGRmMzVjYjYxYjUwYTA5ZmY5OTQzMWQ0Y2Q1
|
15
|
+
NWNjNGU4MDk2ZGQ4MTA5YzQ2ZDM2N2EzNTc0MWZlZDI0Yzg2Mjk=
|
data/lib/deferring.rb
CHANGED
@@ -32,12 +32,15 @@ module Deferring
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def deferred_accepts_nested_attributes_for(*args)
|
35
|
-
|
35
|
+
options = args.extract_options!
|
36
|
+
inverse_association_name = options.fetch(:as, self.name.underscore.to_sym)
|
37
|
+
accepts_nested_attributes_for(*args, options)
|
38
|
+
|
36
39
|
association_name = args.first.to_s
|
37
40
|
|
38
41
|
# teams_attributes=
|
39
42
|
define_method :"#{association_name}_attributes=" do |records|
|
40
|
-
find_or_create_deferred_association(association_name, [],
|
43
|
+
find_or_create_deferred_association(association_name, [], inverse_association_name)
|
41
44
|
|
42
45
|
# Remove the records that are to be destroyed from the ids that are to be
|
43
46
|
# assigned to the DeferredAssociation instance.
|
@@ -110,7 +113,6 @@ module Deferring
|
|
110
113
|
# the save after the parent object has been saved
|
111
114
|
after_save :"perform_deferred_#{association_name}_save!"
|
112
115
|
define_method :"perform_deferred_#{association_name}_save!" do
|
113
|
-
|
114
116
|
find_or_create_deferred_association(association_name, listeners, inverse_association_name)
|
115
117
|
|
116
118
|
# Send the objects of our delegated association to the original
|
@@ -80,11 +80,23 @@ module Deferring
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def objects=(records)
|
83
|
-
@objects = records
|
83
|
+
@objects = records.map do |record|
|
84
|
+
if inverse_name && record.class.reflect_on_association(inverse_name)
|
85
|
+
record.send(:"#{inverse_name}=", parent_record)
|
86
|
+
end
|
87
|
+
record
|
88
|
+
end
|
89
|
+
|
84
90
|
@original_objects = original_association.to_a.clone
|
85
91
|
objects_loaded!
|
86
92
|
|
87
|
-
pending_deletes.each
|
93
|
+
pending_deletes.each do |record|
|
94
|
+
run_deferring_callbacks(:unlink, record) do
|
95
|
+
if inverse_name && record.class.reflect_on_association(inverse_name)
|
96
|
+
record.send(:"#{inverse_name}=", nil)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
88
100
|
pending_creates.each { |record| run_deferring_callbacks(:link, record) }
|
89
101
|
|
90
102
|
@objects
|
@@ -99,6 +111,10 @@ module Deferring
|
|
99
111
|
# but it will probably be filtered after saving and retrieving as well.
|
100
112
|
Array(records).flatten.uniq.each do |record|
|
101
113
|
run_deferring_callbacks(:link, record) do
|
114
|
+
if inverse_name && record.class.reflect_on_association(inverse_name)
|
115
|
+
record.send(:"#{inverse_name}=", parent_record)
|
116
|
+
end
|
117
|
+
|
102
118
|
objects << record
|
103
119
|
end
|
104
120
|
end
|
@@ -111,6 +127,10 @@ module Deferring
|
|
111
127
|
def delete(records)
|
112
128
|
Array(records).flatten.uniq.each do |record|
|
113
129
|
run_deferring_callbacks(:unlink, record) do
|
130
|
+
if inverse_name && record.class.reflect_on_association(inverse_name)
|
131
|
+
record.send(:"#{inverse_name}=", nil)
|
132
|
+
end
|
133
|
+
|
114
134
|
objects.delete(record)
|
115
135
|
end
|
116
136
|
end
|
data/lib/deferring/version.rb
CHANGED
@@ -11,10 +11,125 @@ RSpec.describe 'deferred has_many associations' do
|
|
11
11
|
Issue.create!(subject: 'Make me a sandwich!')
|
12
12
|
end
|
13
13
|
|
14
|
+
let(:bob) { Person.where(name: 'Bob').first }
|
15
|
+
|
14
16
|
let(:printer_issue) { Issue.where(subject: 'Printer PRT-001 jammed').first }
|
15
17
|
let(:db_issue) { Issue.where(subject: 'Database server DB-1337 down').first }
|
16
18
|
let(:sandwich_issue) { Issue.where(subject: 'Make me a sandwich!').first }
|
17
19
|
|
20
|
+
describe 'deferring' do
|
21
|
+
it 'does not create a link until parent is saved' do
|
22
|
+
bob.issues << db_issue << printer_issue
|
23
|
+
expect{ bob.save! }.to change{ Person.find(bob.id).issues.size }.from(0).to(2)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does not unlink until parent is saved' do
|
27
|
+
bob.issue_ids = [db_issue.id, printer_issue.id, sandwich_issue.id]
|
28
|
+
bob.save!
|
29
|
+
|
30
|
+
bob.issues.delete([
|
31
|
+
Issue.find(db_issue.id),
|
32
|
+
Issue.find(sandwich_issue.id)
|
33
|
+
])
|
34
|
+
|
35
|
+
expect{ bob.save }.to change{ Person.find(bob.id).issues.size }.from(3).to(1)
|
36
|
+
end
|
37
|
+
|
38
|
+
xit 'does not create a link when parent is not valid'
|
39
|
+
|
40
|
+
it 'replaces existing records when assigning a new set of records' do
|
41
|
+
bob.issues = [db_issue]
|
42
|
+
|
43
|
+
# A mistake was made, Bob wants to submit a printer and a sandwich issue.
|
44
|
+
bob.issues = [printer_issue, sandwich_issue]
|
45
|
+
|
46
|
+
expect{ bob.save }.to change{ Person.find(bob.id).issues.size }.from(0).to(2)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'sets the belongs_to association of the associated record' do
|
50
|
+
bob.issues << printer_issue
|
51
|
+
expect(bob.issues.first.person).to eq bob
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#collection_singular_ids' do
|
55
|
+
it 'returns ids of saved & unsaved associated records' do
|
56
|
+
bob.issues = [printer_issue, db_issue]
|
57
|
+
expect(bob.issue_ids.size).to eq(2)
|
58
|
+
expect(bob.issue_ids).to eq [printer_issue.id, db_issue.id]
|
59
|
+
|
60
|
+
expect{ bob.save }.to change{ Person.find(bob.id).issue_ids.size }.from(0).to(2)
|
61
|
+
|
62
|
+
expect(bob.issue_ids.size).to eq(2)
|
63
|
+
expect(bob.issue_ids).to eq [printer_issue.id, db_issue.id]
|
64
|
+
end # collection_singular_ids
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#collections_singular_ids=' do
|
68
|
+
it 'sets associated records' do
|
69
|
+
bob.issue_ids = [printer_issue.id, db_issue.id]
|
70
|
+
bob.save
|
71
|
+
expect(bob.issues).to eq [printer_issue, db_issue]
|
72
|
+
expect(bob.issue_ids).to eq [printer_issue.id, db_issue.id]
|
73
|
+
|
74
|
+
bob.reload
|
75
|
+
expect(bob.issues).to eq [printer_issue, db_issue]
|
76
|
+
expect(bob.issue_ids).to eq [printer_issue.id, db_issue.id]
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'replace existing records when assigning a new set of ids of records' do
|
80
|
+
bob.issues = [db_issue]
|
81
|
+
|
82
|
+
bob.issue_ids = [printer_issue.id, sandwich_issue.id]
|
83
|
+
expect(bob.issues.length).to eq(2)
|
84
|
+
|
85
|
+
expect{ bob.save }.to change{ Person.find(bob.id).issues.size }.from(0).to(2)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'clears empty values from the ids to be assigned' do
|
89
|
+
bob.issue_ids = [db_issue.id, '']
|
90
|
+
expect(bob.issues.length).to eq(1)
|
91
|
+
|
92
|
+
expect{ bob.save }.to change{ Person.where(name: 'Bob').first.issues.size }.from(0).to(1)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'sets the belongs_to association of the associated record' do
|
96
|
+
expect(printer_issue.person).to be_nil
|
97
|
+
bob.issue_ids = [printer_issue.id]
|
98
|
+
expect(bob.issues.first.person).to eq bob
|
99
|
+
end
|
100
|
+
end # collections_singular_ids=
|
101
|
+
end
|
102
|
+
|
103
|
+
describe 'accepts_nested_attributes' do
|
104
|
+
it 'should mass-assign' do
|
105
|
+
p = Person.first
|
106
|
+
p.issues << printer_issue << db_issue << sandwich_issue
|
107
|
+
p.save
|
108
|
+
|
109
|
+
# Destroy db and sandwich issues. Keep printer issue.
|
110
|
+
p = Person.first
|
111
|
+
p.attributes = {
|
112
|
+
issues_attributes: [
|
113
|
+
{ id: printer_issue.id },
|
114
|
+
{ id: sandwich_issue.id, _destroy: true },
|
115
|
+
{ id: db_issue.id, _destroy: true }
|
116
|
+
]
|
117
|
+
}
|
118
|
+
expect(p.issues.length).to eq(1)
|
119
|
+
expect(p.issue_ids.sort).to eq([1])
|
120
|
+
|
121
|
+
expect{ p.save! }.to change{ Person.first.issues.size }.from(3).to(1)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'sets the belongs_to association of the associated record' do
|
125
|
+
expect(printer_issue.person).to be_nil
|
126
|
+
bob.attributes = {
|
127
|
+
issues_attributes: [{ id: printer_issue.id }]
|
128
|
+
}
|
129
|
+
expect(bob.issues.first.person).to eq bob
|
130
|
+
end
|
131
|
+
end # accepts_nested_attributes
|
132
|
+
|
18
133
|
describe 'preloading associations' do
|
19
134
|
before do
|
20
135
|
bob = Person.where(name: 'Bob').first
|
@@ -55,10 +170,9 @@ RSpec.describe 'deferred has_many associations' do
|
|
55
170
|
people = Person.all
|
56
171
|
expect(people[1].issues.loaded?).to be_falsey
|
57
172
|
end
|
58
|
-
end
|
173
|
+
end # preloading associations
|
59
174
|
|
60
175
|
describe 'active record api' do
|
61
|
-
|
62
176
|
describe '#build' do
|
63
177
|
it 'builds a new record' do
|
64
178
|
bob = Person.where(name: 'Bob').first
|
@@ -74,6 +188,5 @@ RSpec.describe 'deferred has_many associations' do
|
|
74
188
|
expect(bob.issues.last.person).to eq bob
|
75
189
|
end
|
76
190
|
end
|
77
|
-
end
|
78
|
-
|
191
|
+
end # active record api
|
79
192
|
end
|
data/spec/support/models.rb
CHANGED
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.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robin Roestenburg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|