Skip to content

Commit 461b627

Browse files
author
Carlos Silva
committed
Fix array association inversion and records delete
1 parent d1858e9 commit 461b627

File tree

5 files changed

+57
-26
lines changed

5 files changed

+57
-26
lines changed

lib/torque/postgresql/associations/belongs_to_many_association.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def include?(record)
4747
return include_in_memory?(record) if record.new_record?
4848

4949
(!target.empty? && target.include?(record)) ||
50-
stale_state.include?(record.read_attribute(klass_attr))
50+
stale_state&.include?(record.read_attribute(klass_attr))
5151
end
5252

5353
def load_target
@@ -179,7 +179,7 @@ def read_records_ids(records)
179179
def ids_rewriter(ids, operator)
180180
list = owner[source_attr] ||= []
181181
list = list.public_send(operator, ids)
182-
owner[source_attr] = list.uniq.compact
182+
owner[source_attr] = list.uniq.compact.presence
183183

184184
return if @_building_changes || !owner.persisted?
185185
owner.update_attribute(source_attr, list)
@@ -194,6 +194,10 @@ def concat_records(*)
194194
build_changes { super }
195195
end
196196

197+
def delete_or_destroy(*)
198+
build_changes { super }
199+
end
200+
197201
def difference(a, b)
198202
a - b
199203
end

lib/torque/postgresql/reflection/abstract_reflection.rb

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -103,28 +103,6 @@ def arel_array_to_any(klass_attr, source_attr, klass_type, source_type)
103103

104104
::Arel::Nodes::NamedFunction.new('ANY', [source_attr])
105105
end
106-
107-
# returns either +nil+ or the inverse association name that it finds.
108-
def automatic_inverse_of
109-
return super unless connected_through_array?
110-
111-
if can_find_inverse_of_automatically?(self)
112-
inverse_name = options[:as] || active_record.name.demodulize
113-
inverse_name = ActiveSupport::Inflector.underscore(inverse_name)
114-
inverse_name = ActiveSupport::Inflector.pluralize(inverse_name)
115-
inverse_name = inverse_name.to_sym
116-
117-
begin
118-
reflection = klass._reflect_on_association(inverse_name)
119-
rescue NameError
120-
# Give up: we couldn't compute the klass type so we won't be able
121-
# to find any associations either.
122-
reflection = false
123-
end
124-
125-
return inverse_name if valid_inverse_reflection?(reflection)
126-
end
127-
end
128106
end
129107

130108
::ActiveRecord::Reflection::AbstractReflection.prepend(AbstractReflection)

lib/torque/postgresql/reflection/association_reflection.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,28 @@ def derive_foreign_key
2424
result
2525
end
2626

27+
# returns either +nil+ or the inverse association name that it finds.
28+
def automatic_inverse_of
29+
return super unless connected_through_array?
30+
31+
if can_find_inverse_of_automatically?(self)
32+
inverse_name = options[:as] || active_record.name.demodulize
33+
inverse_name = ActiveSupport::Inflector.underscore(inverse_name)
34+
inverse_name = ActiveSupport::Inflector.pluralize(inverse_name)
35+
inverse_name = inverse_name.to_sym
36+
37+
begin
38+
reflection = klass._reflect_on_association(inverse_name)
39+
rescue NameError
40+
# Give up: we couldn't compute the klass type so we won't be able
41+
# to find any associations either.
42+
reflection = false
43+
end
44+
45+
return inverse_name if valid_inverse_reflection?(reflection)
46+
end
47+
end
48+
2749
end
2850

2951
::ActiveRecord::Reflection::AssociationReflection.prepend(AssociationReflection)

spec/tests/belongs_to_many_spec.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,15 @@
200200
expect(subject.tags[1].name).to be_eql('Test 3')
201201
end
202202

203+
it 'can delete specific records' do
204+
subject.tags << initial
205+
expect(subject.tags.size).to be_eql(1)
206+
207+
subject.tags.delete(initial)
208+
expect(subject.tags.size).to be_eql(0)
209+
expect(subject.reload.tags.size).to be_eql(0)
210+
end
211+
203212
it 'can delete all records' do
204213
subject.tags.concat(FactoryBot.create_list(:tag, 5))
205214
expect(subject.tags.size).to be_eql(5)
@@ -245,11 +254,15 @@
245254
it 'can check if a record is included on the list' do
246255
outside = FactoryBot.create(:tag)
247256
inside = FactoryBot.create(:tag)
257+
258+
expect(subject.tags).not_to be_include(inside)
259+
expect(subject.tags).not_to be_include(outside)
260+
248261
subject.tags << inside
249262

250263
expect(subject.tags).to respond_to(:include?)
251-
expect(subject.tags.include?(inside)).to be_truthy
252-
expect(subject.tags.include?(outside)).to be_falsey
264+
expect(subject.tags).to be_include(inside)
265+
expect(subject.tags).not_to be_include(outside)
253266
end
254267

255268
it 'can append records' do

spec/tests/has_many_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,20 @@
291291
expect(record.tag_ids).to be_eql([subject.id])
292292
end
293293

294+
it 'can perist after accessed in after_create' do
295+
other.belongs_to_many(:tags)
296+
other.after_create { self.tags.to_a }
297+
298+
video = FactoryBot.create(:video)
299+
subject.videos << video
300+
301+
expect(subject.reload.videos.size).to eql(1)
302+
expect(video.reload.tags.size).to eql(1)
303+
304+
other.reset_callbacks(:create)
305+
other._reflections = {}
306+
end
307+
294308
it 'can concat records' do
295309
FactoryBot.create(:video, tag_ids: [subject.id])
296310
expect(subject.videos.size).to be_eql(1)

0 commit comments

Comments
 (0)