Skip to content

Commit a3de8b7

Browse files
committed
Update associations on object delete
Resolves issue #467
1 parent a902a08 commit a3de8b7

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

lib/dynamoid/associations/association.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ def declaration_field_type
5858
:set
5959
end
6060

61+
def disassociate_source
62+
Array(target).each do |target_entry|
63+
target_entry.send(target_association).disassociate(source.hash_key) if target_entry && target_association
64+
end
65+
end
66+
6167
private
6268

6369
# The target class name, either inferred through the association's name or specified in options.

lib/dynamoid/associations/single_association.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def setter(object)
2828
# unsaved changes will be saved. Doesn't delete an associated model from
2929
# DynamoDB.
3030
def delete
31-
target.send(target_association).disassociate(source.hash_key) if target && target_association
31+
disassociate_source
3232
disassociate
3333
target
3434
end
@@ -90,7 +90,7 @@ def empty?
9090

9191
# @private
9292
def associate(hash_key)
93-
target.send(target_association).disassociate(source.hash_key) if target && target_association
93+
disassociate_source
9494
source.update_attribute(source_attribute, Set[hash_key])
9595
end
9696

lib/dynamoid/persistence.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,9 +801,20 @@ def delete
801801

802802
@destroyed = true
803803

804-
Dynamoid.adapter.delete(self.class.table_name, hash_key, options)
804+
Dynamoid.adapter.delete(self.class.table_name, hash_key, options).tap { update_asociations }
805805
rescue Dynamoid::Errors::ConditionalCheckFailedException
806806
raise Dynamoid::Errors::StaleObjectError.new(self, 'delete')
807807
end
808+
809+
private
810+
811+
def update_asociations
812+
self.class.associations.each do |name, options|
813+
begin
814+
send(name).disassociate_source
815+
rescue Aws::DynamoDB::Errors::ResourceNotFoundException
816+
end
817+
end
818+
end
808819
end
809820
end

spec/dynamoid/persistence_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,6 +2597,38 @@ def log_message
25972597
expect { a1.destroy }.to_not raise_error
25982598
end
25992599
end
2600+
2601+
context 'with associations' do
2602+
let!(:user) { User.create }
2603+
let!(:camel_case) { user.camel_case.create }
2604+
let!(:magazine) { user.books.create }
2605+
let!(:monthly) { user.monthly.create }
2606+
let!(:subscription) { user.subscriptions.create }
2607+
2608+
it 'updates belongs_to association' do
2609+
expect do
2610+
user.delete
2611+
end.to change { CamelCase.find(camel_case.id).users.target }.from([user]).to([])
2612+
end
2613+
2614+
it 'updates has_many association' do
2615+
expect do
2616+
user.delete
2617+
end.to change { Magazine.find(magazine.title).owner.target }.from(user).to(nil)
2618+
end
2619+
2620+
it 'updates has_one association' do
2621+
expect do
2622+
user.delete
2623+
end.to change { Subscription.find(monthly.id).customer.target }.from(user).to(nil)
2624+
end
2625+
2626+
it 'updates has_and_belongs_to_many association' do
2627+
expect do
2628+
user.delete
2629+
end.to change { Subscription.find(subscription.id).users.target }.from([user]).to([])
2630+
end
2631+
end
26002632
end
26012633

26022634
describe '.import' do

0 commit comments

Comments
 (0)