deferring 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|