delete_paranoid 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module DeleteParanoid
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -4,29 +4,47 @@ module DeleteParanoid
4
4
  module ActiveRecordExtensions
5
5
  def acts_as_paranoid
6
6
  class << self
7
- alias_method :destroy!, :destroy
7
+ alias_method :delete_all!, :delete_all
8
8
  end
9
+ alias_method :destroy!, :destroy
9
10
  default_scope where(:deleted_at => nil)
10
- include DeleteParanoid::InstanceMethods
11
11
  extend DeleteParanoid::ClassMethods
12
+ include DeleteParanoid::InstanceMethods
12
13
  end
13
14
  end
15
+
14
16
  module ClassMethods
15
- def with_deleted(&block)
17
+ def with_deleted
16
18
  self.unscoped do
17
19
  yield
18
20
  end
19
21
  end
22
+
23
+ def delete_all(conditions = nil)
24
+ update_all ["deleted_at = ?", Time.now.utc], conditions
25
+ end
26
+
27
+ def destroy_all!(conditions = nil)
28
+ if conditions
29
+ where(conditions).destroy_all!
30
+ else
31
+ to_a.each {|object| object.destroy! }.tap { reset }
32
+ end
33
+ end
20
34
  end
35
+
21
36
  module InstanceMethods
22
37
  def destroy
23
38
  if persisted?
24
39
  with_transaction_returning_status do
25
40
  _run_destroy_callbacks do
26
- update_attributes(:deleted_at => Time.now.utc)
41
+ self.deleted_at = Time.now.utc
42
+ self.class.delete_all :id => self.id
27
43
  @destroyed = true
28
44
  end
29
45
  end
46
+ else
47
+ @destroyed = true
30
48
  end
31
49
 
32
50
  freeze
@@ -3,11 +3,16 @@ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
3
3
  ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
4
4
  ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite'])
5
5
 
6
- ActiveRecord::Schema.define(:version => 1) do
6
+ ActiveRecord::Schema.define(:version => 2) do
7
7
  create_table :blogs, :force => true do |t|
8
8
  t.column :title, :string
9
9
  t.column :body, :string
10
10
  t.column :deleted_at, :timestamp
11
11
  end
12
+ create_table :comments, :force => true do |t|
13
+ t.column :blog_id, :integer
14
+ t.column :text, :string
15
+ t.column :deleted_at, :timestamp
16
+ end
12
17
  end
13
18
 
data/test/helper.rb CHANGED
@@ -18,5 +18,130 @@ require 'delete_paranoid'
18
18
  require 'database_setup'
19
19
 
20
20
  class Test::Unit::TestCase
21
+
22
+ def self.should_soft_destroy(subject)
23
+ should "assign deleted_at on #{subject}" do
24
+ assert_not_nil instance_variable_get(:"@#{subject}").deleted_at
25
+ end
26
+ should "set #{subject} to destroyed" do
27
+ assert instance_variable_get(:"@#{subject}").destroyed?
28
+ end
29
+ should "freeze #{subject}" do
30
+ assert instance_variable_get(:"@#{subject}").frozen?
31
+ end
32
+ should "not be found normally" do
33
+ destroyed_subject = instance_variable_get(:"@#{subject}")
34
+ assert_raises ActiveRecord::RecordNotFound do
35
+ destroyed_subject.class.find destroyed_subject.id
36
+ end
37
+ end
38
+ should "be found when in with_deleted block" do
39
+ destroyed_subject = instance_variable_get(:"@#{subject}")
40
+ destroyed_subject.class.with_deleted do
41
+ assert_nothing_raised ActiveRecord::RecordNotFound do
42
+ destroyed_subject.class.find destroyed_subject.id
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ def self.should_hard_destroy(subject)
49
+ should "not be retrievable" do
50
+ destroyed_subject = instance_variable_get(:"@#{subject}")
51
+ assert_raises ActiveRecord::RecordNotFound do
52
+ destroyed_subject.class.find destroyed_subject.id
53
+ end
54
+ end
55
+ should "not be retrievable in with_deleted block" do
56
+ destroyed_subject = instance_variable_get(:"@#{subject}")
57
+ destroyed_subject.class.with_deleted do
58
+ assert_raises ActiveRecord::RecordNotFound do
59
+ destroyed_subject.class.find destroyed_subject.id
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ def self.should_trigger_destroy_callbacks(subject)
66
+ should "call before_destroy callbacks on #{subject}" do
67
+ assert instance_variable_get(:"@#{subject}").called_before_destroy
68
+ end
69
+ should "call after_destroy callbacks on #{subject}" do
70
+ assert instance_variable_get(:"@#{subject}").called_after_destroy
71
+ end
72
+ should "call after_commit_on_destroy callbacks on #{subject}" do
73
+ assert instance_variable_get(:"@#{subject}").called_after_commit_on_destroy
74
+ end
75
+ end
76
+
77
+ def self.should_not_trigger_update_callbacks(subject)
78
+ should "not call before_update callbacks on #{subject}" do
79
+ assert !instance_variable_get(:"@#{subject}").called_before_update
80
+ end
81
+ should "not call after_update callbacks on #{subject}" do
82
+ assert !instance_variable_get(:"@#{subject}").called_after_update
83
+ end
84
+ should "not call after_commit_on_update callbacks on #{subject}" do
85
+ assert !instance_variable_get(:"@#{subject}").called_after_commit_on_update
86
+ end
87
+ end
88
+
21
89
  end
22
90
 
91
+
92
+ module CallbackTester
93
+ ATTRS = %w{ called_before_destroy called_after_destroy called_after_commit_on_destroy called_before_update called_after_update called_after_commit_on_update }
94
+
95
+ def self.included(base)
96
+ base.class_eval do
97
+ attr_accessor *ATTRS
98
+
99
+ before_update :call_me_before_update
100
+ after_update :call_me_after_update
101
+
102
+ before_destroy :call_me_before_destroy
103
+ after_destroy :call_me_after_destroy
104
+
105
+ after_commit :call_me_after_commit_on_destroy, :on => :destroy
106
+ after_commit :call_me_after_commit_on_update, :on => :update
107
+
108
+ alias_method_chain :initialize, :callback_init
109
+ end
110
+ end
111
+
112
+ def initialize_with_callback_init(*args)
113
+ reset_callback_flags!
114
+ initialize_without_callback_init(*args)
115
+ end
116
+
117
+ def reset_callback_flags!
118
+ ATTRS.each do |attr|
119
+ send("#{attr}=", false)
120
+ end
121
+ end
122
+
123
+ def call_me_before_destroy
124
+ @called_before_destroy = true
125
+ end
126
+
127
+ def call_me_after_destroy
128
+ @called_after_destroy = true
129
+ end
130
+
131
+ def call_me_after_commit_on_destroy
132
+ @called_after_commit_on_destroy = true
133
+ end
134
+
135
+ def call_me_before_update
136
+ @called_before_update = true
137
+ end
138
+
139
+ def call_me_after_update
140
+ @called_after_update = true
141
+ end
142
+
143
+ def call_me_after_commit_on_update
144
+ @called_after_commit_on_update = true
145
+ end
146
+
147
+ end
@@ -2,62 +2,87 @@ require File.join(File.dirname(__FILE__), 'helper')
2
2
 
3
3
  class TestDeleteParanoid < Test::Unit::TestCase
4
4
  class Blog < ActiveRecord::Base
5
+ has_many :comments, :dependent => :destroy
5
6
  acts_as_paranoid
6
-
7
- attr_accessor :called_before_destroy, :called_after_destroy, :called_after_commit_on_destroy
8
-
9
- before_destroy :call_me_before_destroy
10
- after_destroy :call_me_after_destroy
11
-
12
- after_commit :call_me_after_commit_on_destroy, :on => :destroy
13
-
14
- def initialize(*attrs)
15
- @called_before_destroy = @called_after_destroy = @called_after_commit_on_destroy = false
16
- super(*attrs)
17
- end
18
-
19
- def call_me_before_destroy
20
- @called_before_destroy = true
21
- end
7
+ attr_accessible :title
8
+ include CallbackTester
9
+ end
22
10
 
23
- def call_me_after_destroy
24
- @called_after_destroy = true
11
+ class Comment < ActiveRecord::Base
12
+ acts_as_paranoid
13
+ attr_accessible :text
14
+ include CallbackTester
15
+ end
16
+
17
+ context 'with paranoid instance' do
18
+ setup do
19
+ @blog = Blog.new
25
20
  end
26
-
27
- def call_me_after_commit_on_destroy
28
- @called_after_commit_on_destroy = true
21
+ should 'have destroy! method' do
22
+ assert @blog.respond_to? :destroy!
29
23
  end
30
24
  end
31
-
32
25
  context 'with paranoid class' do
33
- should 'have destroy! method' do
34
- assert Blog.respond_to? :destroy!
26
+ should 'have delete_all! method' do
27
+ assert Blog.respond_to? :delete_all!
35
28
  end
29
+
36
30
  context 'when on instance destroyed softly' do
37
31
  setup do
38
32
  @blog = Blog.create! :title => 'foo'
39
33
  @blog.destroy
40
34
  end
41
- should 'not be included in all results' do
42
- assert !Blog.all.include?(@blog)
43
- end
44
- should 'be included when wrapped in with_deleted block' do
45
- Blog.with_deleted do
46
- assert Blog.all.include?(@blog)
35
+
36
+ should_soft_destroy :blog
37
+ should_trigger_destroy_callbacks :blog
38
+ should_not_trigger_update_callbacks :blog
39
+ end
40
+
41
+ context 'when an instance with dependents is destroyed softly' do
42
+ setup do
43
+ @comment = Comment.create! :text => 'bar'
44
+ @blog = Blog.create!(:title => 'foo').tap do |blog|
45
+ blog.comments << @comment
47
46
  end
47
+ @blog.destroy
48
48
  end
49
- should "call before_destroy callbacks" do
50
- assert @blog.called_before_destroy
51
- end
52
- should "call after_destroy callbacks" do
53
- assert @blog.called_after_destroy
54
- end
55
- should "call after_commit_on_destroy callbacks" do
56
- assert @blog.called_after_commit_on_destroy
57
- end
49
+
50
+ should_soft_destroy :blog
51
+ should_trigger_destroy_callbacks :blog
52
+ should_not_trigger_update_callbacks :blog
58
53
 
54
+ should_soft_destroy :comment
55
+ should_trigger_destroy_callbacks :comment
56
+ # should_not_trigger_update_callbacks :comment
59
57
  end
58
+
59
+ context "when on instance destroyed hardly" do
60
+ setup do
61
+ @blog = Blog.create! :title => 'foo'
62
+ @blog.destroy!
63
+ end
60
64
 
61
- should 'hard delete with destroy!'
65
+ should_hard_destroy :blog
66
+ should_trigger_destroy_callbacks :blog
67
+ should_not_trigger_update_callbacks :blog
68
+ end
69
+
70
+ context 'when an instance with dependents is destroyed hardly' do
71
+ setup do
72
+ @comment = Comment.create! :text => 'bar'
73
+ @blog = Blog.create!(:title => 'foo').tap do |blog|
74
+ blog.comments << @comment
75
+ end
76
+ @blog.destroy!
77
+ end
78
+
79
+ should_hard_destroy :blog
80
+ should_trigger_destroy_callbacks :blog
81
+ should_not_trigger_update_callbacks :blog
82
+ # should_hard_destroy :comment
83
+ should_trigger_destroy_callbacks :comment
84
+ # should_not_trigger_update_callbacks :comment
85
+ end
86
+
62
87
  end
63
88
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delete_paranoid
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Sonnek
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-01 00:00:00 -05:00
18
+ date: 2011-04-04 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency