Skip to content

Commit

Permalink
When a record is deleted it should use unscoped association calls
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor Kmita committed Sep 23, 2014
1 parent b62b952 commit ed66567
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
40 changes: 40 additions & 0 deletions lib/zombie_record/restorable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Restorable
default_scope { where(deleted_at: nil) }

define_callbacks :restore
after_initialize :associate_with_deleted, unless: :associated?
end

# Override Rails' #destroy for soft-delete functionality
Expand Down Expand Up @@ -53,6 +54,45 @@ def deleted?

private

def associate_with_deleted
self.class.reflect_on_all_associations.each do |association|

if association.options[:polymorphic]
klass = public_send("#{association.name}_type".to_sym).constantize
next unless klass.include?(Restorable)
associate_method(association, klass)
next
end

next unless association.klass.include?(Restorable)
associate_method(association)
end
Restorable.associated_classes << self.class
end

def associate_method(association, klass = nil)
self.class.send(:define_method, association.name) do
if deleted?
case association.macro
when :has_one, :belongs_to
(klass || association.klass).unscoped { super() }
when :has_many
super().deleted
end
else
super()
end
end
end

def associated?
Restorable.associated_classes.include?(self.class)
end

def self.associated_classes
@@associated_classes ||= []
end

def restore_associated_records!
self.class.reflect_on_all_associations.each do |association|
# Only restore associations that are automatically destroyed alongside
Expand Down
14 changes: 14 additions & 0 deletions spec/restorable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,18 @@
book.should_not be_deleted
end
end

describe "#associate_with_deleted" do
it "removes default scope from associations when deleted" do
cover = Cover.create!
book = Book.create!(cover: cover)

book.destroy
Book.find_by_id(book.id).should be_nil
Cover.find_by_id(cover.id).should be_nil

book = Book.deleted.first
book.cover.should == cover
end
end
end

0 comments on commit ed66567

Please sign in to comment.