immortal 1.0.5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 60ac9bd43b41aa290750329470ab9cd76e8adcb3
4
+ data.tar.gz: a779e1fb76253a4148f62e186c347be7ed19c847
5
+ SHA512:
6
+ metadata.gz: 34bddc9c389145c501948b6255821a30424cd126fca8e6367a1ee65f7d99d32ea96fe53c684575d3c0c184f9c962fca802c1786e351e6b65d4ce858669ad70cf
7
+ data.tar.gz: a34d764cdc236d6cb6f055c32bdeb2eab35448390171af5988eaa0accca696e2a843d87f683cd65a9f753624b97168fb1569e5d4994c8ddfd4e85fb9bdda9db2
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
1
  pkg/*
2
2
  *.gem
3
3
  .bundle
4
+ .Gemfile.lock
5
+ Gemfile.lock
data/Gemfile CHANGED
@@ -2,14 +2,3 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in immortal.gemspec
4
4
  gemspec
5
-
6
- group :test, :development do
7
-
8
- # gem "ruby-debug", "~> 0.10.4", :require => "ruby-debug", :platform => :ruby_18
9
-
10
- # gem "ruby-debug19", :require => "ruby-debug", :platform => :ruby_19
11
- # # Uncomment this and rebundle to use the debugger under 1.9.3
12
- # TODO: Remove this when ruby-debug-base19-0.11.26 is published
13
- # gem "ruby-debug-base19", "0.11.26", :platform => :ruby_19
14
-
15
- end
data/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) Teambox
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -57,3 +57,15 @@ If you want to improve immortal
57
57
  - 0.1.3 fix bug where join model is not immortal
58
58
  - 0.1.2 fix loading issue when the `deleted` column doesn't exist (or even the table)
59
59
  - 0.1.1 fix behavior with `has_many :through` associations
60
+
61
+ ## License
62
+
63
+ (The MIT License)
64
+
65
+ Copyright (c) Teambox
66
+
67
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
68
+
69
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
70
+
71
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,22 +1,28 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
- s.name = "immortal"
6
- s.version = '1.0.5'
7
- s.authors = ["Jordi Romero", "Saimon Moore"]
8
- s.email = ["jordi@jrom.net", "saimon@saimonmoore.net"]
9
- s.homepage = "http://github.com/teambox/immortal"
10
- s.summary = %q{Replacement for acts_as_paranoid for Rails 3}
11
- s.description = %q{Typical paranoid gem built for Rails 3 and with the minimum code needed to satisfy acts_as_paranoid's API}
5
+ s.name = 'immortal'
6
+ s.version = '2.0.0'
7
+ s.authors = [
8
+ 'Jordi Romero', 'Saimon Moore', 'Pau Ramon', 'Carlos Saura', 'Andres Bravo',
9
+ 'Fran Casas', 'Pau Perez'
10
+ ]
11
+ s.email = ['jordi@jrom.net', 'saimon@saimonmoore.net']
12
+ s.homepage = 'http://github.com/teambox/immortal'
13
+ s.summary = 'Replacement for acts_as_paranoid for Rails 4'
14
+ s.description = 'Typical paranoid gem built for Rails 4 and with the ' \
15
+ "minimum code needed to satisfy acts_as_paranoid's API"
16
+ s.license = 'MIT'
12
17
 
13
18
  s.files = `git ls-files`.split("\n")
14
19
  s.test_files = `git ls-files -- {spec}/*`.split("\n")
15
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
- s.require_paths = ["lib"]
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
21
+ s.require_paths = ['lib']
17
22
 
18
- s.add_dependency 'activerecord', '~> 3.1.1'
23
+ s.add_dependency 'activerecord', '~> 4.0.0'
19
24
  s.add_development_dependency 'rspec', '~> 2.6.0'
20
25
  s.add_development_dependency 'sqlite3'
21
-
26
+ s.add_development_dependency 'byebug'
27
+ s.add_development_dependency 'rake', '~> 10.0'
22
28
  end
@@ -8,19 +8,6 @@ module Immortal
8
8
  base.send :include, BelongsTo
9
9
  base.class_eval do
10
10
  class << self
11
-
12
- # In has_many :through => join_model we have to explicitly add
13
- # the 'not deleted' scope, otherwise it will take all the rows
14
- # from the join model
15
- def has_many_mortal(association_id, options = {}, &extension)
16
- has_many_immortal(association_id, options, &extension).tap do
17
- # FIXME This must be re-implemented after the ActiveRecord internals refactor in 3.1
18
- end
19
- end
20
-
21
- alias_method :has_many_immortal, :has_many
22
- alias_method :has_many, :has_many_mortal
23
-
24
11
  alias :mortal_delete_all :delete_all
25
12
  alias :delete_all :immortal_delete_all
26
13
  end
@@ -37,26 +24,20 @@ module Immortal
37
24
  new_scope = self.unscoped
38
25
  our_scope = self.current_scope || self.unscoped
39
26
 
40
- non_immortal_constraints = our_scope.arel.constraints.select do |constraint|
41
- !constraint.to_sql.include?('deleted')
42
- end
43
-
44
- non_immortal_constraints_sql = non_immortal_constraints.to_a.map do |constraint|
45
- constraint.to_sql
46
- end.join(' AND ')
27
+ non_immortal_constraints_sql = our_scope.arel.constraints.to_a.map do |constraint|
28
+ constraint.to_sql.split('AND').reject{|clause| clause.include?('deleted')}
29
+ end.flatten.join(' AND ')
47
30
 
48
31
  new_scope = new_scope.merge(our_scope.except(:where))
49
32
  new_scope = new_scope.where(non_immortal_constraints_sql)
50
33
 
51
- unscoped do
52
- with_scope(new_scope) do
53
- yield
54
- end
34
+ unscoped.merge(new_scope).scoping do
35
+ yield
55
36
  end
56
37
  end
57
38
 
58
39
  def exists?(id = false)
59
- where(:deleted => false).exists?(id)
40
+ where(deleted: false).exists?(id)
60
41
  end
61
42
 
62
43
  def count_with_deleted(*args)
@@ -67,24 +48,38 @@ module Immortal
67
48
 
68
49
  def count_only_deleted(*args)
69
50
  without_default_scope do
70
- where(:deleted => true).count(*args)
51
+ where(deleted: true).count(*args)
52
+ end
53
+ end
54
+
55
+ def where_with_deleted(*args)
56
+ without_default_scope do
57
+ where(*args)
71
58
  end
72
59
  end
73
60
 
74
61
  def find_with_deleted(*args)
62
+ ActiveSupport::Deprecation.warn('[immortal] we are deprecating #find_with_deleted use where_with_deleted instead')
75
63
  without_default_scope do
76
64
  find(*args)
77
65
  end
78
66
  end
79
67
 
68
+ def where_only_deleted(*args)
69
+ without_default_scope do
70
+ where(deleted: true).where(args)
71
+ end
72
+ end
73
+
80
74
  def find_only_deleted(*args)
75
+ ActiveSupport::Deprecation.warn('[immortal] we are deprecating #find_only_deleted use where_only_deleted instead')
81
76
  without_default_scope do
82
- where(:deleted => true).find(*args)
77
+ where(deleted: true).find(*args)
83
78
  end
84
79
  end
85
80
 
86
81
  def immortal_delete_all(conditions = nil)
87
- unscoped.update_all({:deleted => 1}, conditions)
82
+ unscoped.where(conditions).update_all(deleted: 1)
88
83
  end
89
84
 
90
85
  def delete_all!(*args)
@@ -92,7 +87,7 @@ module Immortal
92
87
  end
93
88
 
94
89
  def undeleted_clause_sql
95
- unscoped.where(arel_table[:deleted].eq(nil).or(arel_table[:deleted].eq(false))).constraints.first.to_sql
90
+ unscoped.where(deleted: false).constraints.first.to_sql
96
91
  end
97
92
 
98
93
  def deleted_clause_sql
@@ -103,16 +98,23 @@ module Immortal
103
98
 
104
99
  module InstanceMethods
105
100
  def self.included(base)
101
+ unless base.table_exists? && base.columns_hash["deleted"] && !base.columns_hash["deleted"].null
102
+ Kernel.warn "[Immortal] The 'deleted' column in #{base.to_s} is nullable, change the column to not accept NULL values"
103
+ end
104
+
106
105
  base.class_eval do
107
- default_scope where(arel_table[:deleted].eq(nil).or(arel_table[:deleted].eq(false))) if arel_table[:deleted]
106
+ default_scope { ->{ where(deleted: false) } } if arel_table[:deleted]
107
+
108
108
  alias :mortal_destroy :destroy
109
109
  alias :destroy :immortal_destroy
110
110
  end
111
111
  end
112
112
 
113
113
  def immortal_destroy
114
- run_callbacks :destroy do
115
- destroy_without_callbacks
114
+ with_transaction_returning_status do
115
+ run_callbacks :destroy do
116
+ destroy_without_callbacks
117
+ end
116
118
  end
117
119
  end
118
120
 
@@ -121,15 +123,23 @@ module Immortal
121
123
  end
122
124
 
123
125
  def destroy_without_callbacks
124
- self.class.unscoped.update_all({ :deleted => true }, "id = #{self.id}")
126
+ self.class.unscoped.where(id: id).update_all(deleted: true, updated_at: current_time_from_proper_timezone)
127
+ @destroyed = true
125
128
  reload
126
129
  freeze
127
130
  end
128
131
 
129
132
  def recover!
130
- self.class.unscoped.update_all({ :deleted => false }, "id = #{self.id}")
133
+ self.class.unscoped.where(id: id).update_all(deleted: false, updated_at: current_time_from_proper_timezone)
134
+ @destroyed = false
131
135
  reload
132
136
  end
133
137
 
138
+ private
139
+
140
+ def current_time_from_proper_timezone
141
+ ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
142
+ end
143
+
134
144
  end
135
145
  end
@@ -8,8 +8,8 @@ module Immortal
8
8
  class << self
9
9
 
10
10
  # Add with/how_deleted singular association readers
11
- def belongs_to_mortal(name, options = {})
12
- ::Immortal::BelongsToBuilder.build(self, name, options)
11
+ def belongs_to_mortal(name, scope = nil, options = {})
12
+ ::Immortal::BelongsToBuilder.build(self, name, scope, options)
13
13
  end
14
14
 
15
15
  alias_method :belongs_to_immortal, :belongs_to
@@ -12,15 +12,19 @@ module Immortal
12
12
 
13
13
  private
14
14
 
15
+ def supports_indetity_map?
16
+ defined?(ActiveRecord::IdentityMap) && ActiveRecord::IdentityMap.enabled?
17
+ end
18
+
15
19
  def reset_with_deleted
16
20
  @with_deleted_loaded = false
17
- ActiveRecord::IdentityMap.remove(with_deleted_target) if ActiveRecord::IdentityMap.enabled? && with_deleted_target
21
+ ActiveRecord::IdentityMap.remove(with_deleted_target) if supports_indetity_map? && with_deleted_target
18
22
  @with_deleted_target = nil
19
23
  end
20
24
 
21
25
  def reset_only_deleted
22
26
  @only_deleted_loaded = false
23
- ActiveRecord::IdentityMap.remove(only_deleted_target) if ActiveRecord::IdentityMap.enabled? && only_deleted_target
27
+ ActiveRecord::IdentityMap.remove(only_deleted_target) if supports_indetity_map? && only_deleted_target
24
28
  @only_deleted_target = nil
25
29
  end
26
30
 
@@ -75,7 +79,7 @@ module Immortal
75
79
  def load_with_deleted_target
76
80
  if find_with_deleted_target?
77
81
  begin
78
- if ActiveRecord::IdentityMap.enabled? && association_class && association_class.respond_to?(:base_class)
82
+ if supports_indetity_map? && association_class && association_class.respond_to?(:base_class)
79
83
  @with_deleted_target = ActiveRecord::IdentityMap.get(association_class, owner[reflection.foreign_key])
80
84
  end
81
85
  rescue NameError
@@ -93,7 +97,7 @@ module Immortal
93
97
  def load_only_deleted_target
94
98
  if find_only_deleted_target?
95
99
  begin
96
- if ActiveRecord::IdentityMap.enabled? && association_class && association_class.respond_to?(:base_class)
100
+ if supports_indetity_map? && association_class && association_class.respond_to?(:base_class)
97
101
  @only_deleted_target = ActiveRecord::IdentityMap.get(association_class, owner[reflection.foreign_key])
98
102
  end
99
103
  rescue NameError
@@ -132,14 +136,14 @@ module Immortal
132
136
  def find_with_deleted_target
133
137
  return nil unless klass
134
138
  klass.unscoped do
135
- scoped.first.tap { |record| set_inverse_instance(record) }
139
+ scope.first.tap { |record| set_inverse_instance(record) }
136
140
  end
137
141
  end
138
142
 
139
143
  def find_only_deleted_target
140
144
  return nil unless klass
141
145
  klass.unscoped do
142
- scoped.where(:deleted => true).first.tap { |record| set_inverse_instance(record) }
146
+ scope.where(deleted: true).first.tap { |record| set_inverse_instance(record) }
143
147
  end
144
148
  end
145
149
 
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
3
  describe Immortal do
4
4
  before do
5
- @m = ImmortalModel.create! :title => 'testing immortal'
5
+ @m = ImmortalModel.create! title: 'testing immortal'
6
6
  end
7
7
 
8
8
  it "should not be deleted from the database using #destroy" do
@@ -21,6 +21,12 @@ describe Immortal do
21
21
  @m.should_not be_changed
22
22
  end
23
23
 
24
+ it "should not be dirty using #destroy" do
25
+ expect {
26
+ @m.destroy
27
+ }.to change(@m, :updated_at)
28
+ end
29
+
24
30
  it "should be deleted from the database using #destroy!" do
25
31
  expect {
26
32
  @m.destroy!
@@ -45,7 +51,7 @@ describe Immortal do
45
51
  end
46
52
 
47
53
  it "should count undeleted records by default" do
48
- @m2 = ImmortalModel.create! :title => 'testing immortal again'
54
+ @m2 = ImmortalModel.create! title: 'testing immortal again'
49
55
  ImmortalModel.count_only_deleted.should == 0
50
56
 
51
57
  @m.destroy
@@ -54,7 +60,7 @@ describe Immortal do
54
60
  end
55
61
 
56
62
  it "should find only deleted records" do
57
- @m2 = ImmortalModel.create! :title => 'testing immortal again'
63
+ @m2 = ImmortalModel.create! title: 'testing immortal again'
58
64
  expect {
59
65
  ImmortalModel.find_only_deleted(@m.id)
60
66
  }.to raise_error(ActiveRecord::RecordNotFound)
@@ -68,7 +74,7 @@ describe Immortal do
68
74
  end
69
75
 
70
76
  it "should be able to count undeleted records" do
71
- @m2 = ImmortalModel.create! :title => 'testing immortal again'
77
+ @m2 = ImmortalModel.create! title: 'testing immortal again'
72
78
  ImmortalModel.count.should == 2
73
79
 
74
80
  @m.destroy
@@ -77,7 +83,7 @@ describe Immortal do
77
83
  end
78
84
 
79
85
  it "should be able to count all the records including deleted" do
80
- @m2 = ImmortalModel.create! :title => 'testing immortal again'
86
+ @m2 = ImmortalModel.create! title: 'testing immortal again'
81
87
  @m.destroy
82
88
  ImmortalModel.count_with_deleted.should == 2
83
89
  end
@@ -89,8 +95,8 @@ describe Immortal do
89
95
  end
90
96
 
91
97
  it "should calculate without deleted" do
92
- @m2 = ImmortalModel.create! :value => 10
93
- @m3 = ImmortalModel.create! :value => 20
98
+ @m2 = ImmortalModel.create! value: 10
99
+ @m3 = ImmortalModel.create! value: 20
94
100
  ImmortalModel.calculate(:sum, :value).should == 30
95
101
  @m2.destroy
96
102
  ImmortalModel.calculate(:sum, :value).should == 20
@@ -106,6 +112,19 @@ describe Immortal do
106
112
  @m.after_d.should be_true
107
113
  end
108
114
 
115
+ it "should execute the after_commit callback when immortally destroyed" do
116
+ @m.after_commit = false
117
+ @m.destroy
118
+ @m.after_commit.should be_true
119
+ end
120
+
121
+ it "should not return true when a before hook halts" do
122
+ @m.before_return = false
123
+ @m.after_commit = false
124
+ @m.destroy.should be_false
125
+ @m.after_commit.should_not be_true
126
+ end
127
+
109
128
  it "should not execute the before_update callback when immortally destroyed" do
110
129
  @m.destroy
111
130
  @m.before_u.should be_nil
@@ -148,22 +167,17 @@ describe Immortal do
148
167
  it "should be recoverable" do
149
168
  @m.destroy
150
169
  @m = ImmortalModel.find_with_deleted(@m.id)
151
- @m.recover!
170
+ expect {
171
+ @m.recover!
172
+ }.to change(@m, :updated_at)
152
173
  @m.should_not be_frozen
153
174
  @m.should_not be_changed
154
175
  ImmortalModel.first.should == @m
155
176
  end
156
177
 
157
- it "should consider an object with deleted = nil as not deleted" do
158
- @m2 = ImmortalModel.create! :deleted => nil
159
- @m2.deleted.should be_nil
160
- @m2.should_not be_deleted
161
- ImmortalModel.count.should == 2
162
- end
163
-
164
178
  it "should consider an Many-to-many association with through as deleted when the join is deleted." do
165
- @n = ImmortalNode.create! :title => 'testing association'
166
- @join = ImmortalJoin.create! :immortal_model => @m, :immortal_node => @n
179
+ @n = ImmortalNode.create! title: 'testing association'
180
+ @join = ImmortalJoin.create! immortal_model: @m, immortal_node: @n
167
181
 
168
182
  @m.nodes.count.should == 1
169
183
  @n.models.count.should == 1
@@ -175,14 +189,14 @@ describe Immortal do
175
189
  end
176
190
 
177
191
  it "should only immortally delete scoped associations, NOT ALL RECORDS" do
178
- n1 = ImmortalNode.create! :title => 'testing association 1'
179
- j1 = ImmortalJoin.create! :immortal_model => @m, :immortal_node => n1
192
+ n1 = ImmortalNode.create! title: 'testing association 1'
193
+ j1 = ImmortalJoin.create! immortal_model: @m, immortal_node: n1
180
194
 
181
- n2 = ImmortalNode.create! :title => 'testing association 2'
182
- j2 = ImmortalJoin.create! :immortal_model => @m, :immortal_node => n2
195
+ n2 = ImmortalNode.create! title: 'testing association 2'
196
+ j2 = ImmortalJoin.create! immortal_model: @m, immortal_node: n2
183
197
 
184
- n3 = ImmortalNode.create! :title => 'testing association 3'
185
- j3 = ImmortalJoin.create! :immortal_node => n3
198
+ n3 = ImmortalNode.create! title: 'testing association 3'
199
+ j3 = ImmortalJoin.create! immortal_node: n3
186
200
 
187
201
  @m.destroy
188
202
 
@@ -199,9 +213,9 @@ describe Immortal do
199
213
  end
200
214
 
201
215
  it "should reload immortal polymorphic associations using default reader" do
202
- node = ImmortalNode.create! :title => 'testing association 1'
203
- target_1 = ImmortalSomeTarget.create! :title => 'target 1'
204
- target_2 = ImmortalSomeOtherTarget.create! :title => 'target 2'
216
+ node = ImmortalNode.create! title: 'testing association 1'
217
+ target_1 = ImmortalSomeTarget.create! title: 'target 1'
218
+ target_2 = ImmortalSomeOtherTarget.create! title: 'target 2'
205
219
 
206
220
  node.target.should be_nil
207
221
  node.target = target_1
@@ -216,9 +230,9 @@ describe Immortal do
216
230
 
217
231
  it "should reload immortal polymorphic associations using deleted reader" do
218
232
  #setup
219
- node = ImmortalNode.create! :title => 'testing association 1'
220
- target_1 = ImmortalSomeTarget.create! :title => 'target 1'
221
- target_2 = ImmortalSomeOtherTarget.create! :title => 'target 2'
233
+ node = ImmortalNode.create! title: 'testing association 1'
234
+ target_1 = ImmortalSomeTarget.create! title: 'target 1'
235
+ target_2 = ImmortalSomeOtherTarget.create! title: 'target 2'
222
236
 
223
237
  #confirm initial state
224
238
  node.target.should be_nil
@@ -250,9 +264,9 @@ describe Immortal do
250
264
 
251
265
  it "should reload immortal polymorphic associations using deleted reader (direct assignment)" do
252
266
  #setup
253
- node = ImmortalNode.create! :title => 'testing association 1'
254
- target_1 = ImmortalSomeTarget.create! :title => 'target 1'
255
- target_2 = ImmortalSomeOtherTarget.create! :title => 'target 2'
267
+ node = ImmortalNode.create! title: 'testing association 1'
268
+ target_1 = ImmortalSomeTarget.create! title: 'target 1'
269
+ target_2 = ImmortalSomeOtherTarget.create! title: 'target 2'
256
270
 
257
271
  #confirm initial state
258
272
  node.target.should be_nil
@@ -282,9 +296,9 @@ describe Immortal do
282
296
 
283
297
  it "deleted readers should respect staleness" do
284
298
  #setup
285
- node = ImmortalNode.create! :title => 'testing association 1'
286
- target_1 = ImmortalSomeTarget.create! :title => 'target 1'
287
- target_2 = ImmortalSomeOtherTarget.create! :title => 'target 2'
299
+ node = ImmortalNode.create! title: 'testing association 1'
300
+ target_1 = ImmortalSomeTarget.create! title: 'target 1'
301
+ target_2 = ImmortalSomeOtherTarget.create! title: 'target 2'
288
302
 
289
303
  #confirm initial state
290
304
  node.target.should be_nil
@@ -324,12 +338,12 @@ describe Immortal do
324
338
  end
325
339
 
326
340
  it "should not unscope associations when using with_deleted scope" do
327
- m1 = ImmortalModel.create! :title => 'previously created model'
328
- n1 = ImmortalNode.create! :title => 'previously created association'
329
- j1 = ImmortalJoin.create! :immortal_model => m1, :immortal_node => n1
341
+ m1 = ImmortalModel.create! title: 'previously created model'
342
+ n1 = ImmortalNode.create! title: 'previously created association'
343
+ ImmortalJoin.create! immortal_model: m1, immortal_node: n1
330
344
 
331
- @n = ImmortalNode.create! :title => 'testing association'
332
- @join = ImmortalJoin.create! :immortal_model => @m, :immortal_node => @n
345
+ @n = ImmortalNode.create! title: 'testing association'
346
+ @join = ImmortalJoin.create! immortal_model: @m, immortal_node: @n
333
347
 
334
348
  @join.destroy
335
349
 
@@ -341,12 +355,12 @@ describe Immortal do
341
355
  end
342
356
 
343
357
  it "should not unscope associations when using only_deleted scope" do
344
- m1 = ImmortalModel.create! :title => 'previously created model'
345
- n1 = ImmortalNode.create! :title => 'previously created association'
346
- j1 = ImmortalJoin.create! :immortal_model => m1, :immortal_node => n1
358
+ m1 = ImmortalModel.create! title: 'previously created model'
359
+ n1 = ImmortalNode.create! title: 'previously created association'
360
+ ImmortalJoin.create! immortal_model: m1, immortal_node: n1
347
361
 
348
- @n = ImmortalNode.create! :title => 'testing association'
349
- @join = ImmortalJoin.create! :immortal_model => @m, :immortal_node => @n
362
+ @n = ImmortalNode.create! title: 'testing association'
363
+ @join = ImmortalJoin.create! immortal_model: @m, immortal_node: @n
350
364
 
351
365
  @join.destroy
352
366
 
@@ -358,4 +372,12 @@ describe Immortal do
358
372
  @n.joins.count_only_deleted.should == 1
359
373
  end
360
374
 
375
+ it 'warn when deleted column is nullable' do
376
+ Kernel.should_receive(:warn)
377
+
378
+ class ImmortalNullableDeleted
379
+ include Immortal
380
+ end
381
+ end
382
+
361
383
  end
@@ -15,7 +15,7 @@ RSpec.configure do |config|
15
15
  end
16
16
 
17
17
 
18
- ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
18
+ ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
19
19
  ActiveRecord::Base.logger = Logger.new(STDOUT) if ENV['DEBUG']
20
20
 
21
21
  old_stdout = $stdout
@@ -26,13 +26,13 @@ begin
26
26
  create_table :immortal_models do |t|
27
27
  t.string :title
28
28
  t.integer :value
29
- t.boolean :deleted, :default => false
29
+ t.boolean :deleted, default: false, null: false
30
30
  t.timestamps
31
31
  end
32
32
  create_table :immortal_joins do |t|
33
33
  t.integer :immortal_model_id
34
34
  t.integer :immortal_node_id
35
- t.boolean :deleted, :default => false
35
+ t.boolean :deleted, default: false, null: false
36
36
  t.timestamps
37
37
  end
38
38
  create_table :immortal_nodes do |t|
@@ -40,19 +40,25 @@ begin
40
40
  t.string :target_type
41
41
  t.string :title
42
42
  t.integer :value
43
- t.boolean :deleted, :default => false
43
+ t.boolean :deleted, default: false, null: false
44
44
  t.timestamps
45
45
  end
46
46
 
47
47
  create_table :immortal_some_targets do |t|
48
48
  t.string :title
49
- t.boolean :deleted, :default => false
49
+ t.boolean :deleted, default: false, null: false
50
50
  t.timestamps
51
51
  end
52
52
 
53
53
  create_table :immortal_some_other_targets do |t|
54
54
  t.string :title
55
- t.boolean :deleted, :default => false
55
+ t.boolean :deleted, default: false, null: false
56
+ t.timestamps
57
+ end
58
+
59
+ create_table :immortal_nullable_deleteds do |t|
60
+ t.string :title
61
+ t.boolean :deleted, default: false
56
62
  t.timestamps
57
63
  end
58
64
  end
@@ -64,53 +70,56 @@ class ImmortalJoin < ActiveRecord::Base
64
70
  include Immortal
65
71
 
66
72
  belongs_to :immortal_model
67
- belongs_to :immortal_node, :dependent => :destroy
73
+ belongs_to :immortal_node, dependent: :destroy
68
74
  end
69
75
 
70
76
  class ImmortalNode < ActiveRecord::Base
71
77
  include Immortal
72
78
 
73
79
  has_many :immortal_joins
74
- has_many :immortal_models, :through => :immortal_joins
80
+ has_many :immortal_models, through: :immortal_joins
75
81
 
76
- has_many :joins, :class_name => 'ImmortalJoin'
77
- has_many :models, :through => :joins, :source => :immortal_model
82
+ has_many :joins, class_name: 'ImmortalJoin'
83
+ has_many :models, through: :joins, source: :immortal_model
78
84
 
79
- belongs_to :target, :polymorphic => true
85
+ belongs_to :target, polymorphic: true
80
86
  end
81
87
 
82
88
  class ImmortalSomeTarget < ActiveRecord::Base
83
89
  include Immortal
84
90
 
85
- has_many :immortal_nodes, :as => :target
91
+ has_many :immortal_nodes, as: :target
86
92
  end
87
93
 
88
94
  class ImmortalSomeOtherTarget < ActiveRecord::Base
89
95
  include Immortal
90
96
 
91
- has_many :immortal_nodes, :as => :target
97
+ has_many :immortal_nodes, as: :target
92
98
  end
93
99
 
94
100
 
95
101
  class ImmortalModel < ActiveRecord::Base
96
102
  include Immortal
97
103
 
98
- has_many :immortal_nodes, :through => :immortal_joins, :dependent => :destroy
99
- has_many :immortal_joins, :dependent => :delete_all
104
+ has_many :immortal_nodes, through: :immortal_joins, dependent: :destroy
105
+ has_many :immortal_joins, dependent: :delete_all
100
106
 
101
- has_many :joins, :class_name => 'ImmortalJoin', :dependent => :delete_all
102
- has_many :nodes, :through => :joins, :source => :immortal_node, :dependent => :destroy
107
+ has_many :joins, class_name: 'ImmortalJoin', dependent: :delete_all
108
+ has_many :nodes, through: :joins, source: :immortal_node, dependent: :destroy
103
109
 
104
- attr_accessor :before_d, :after_d, :before_u, :after_u
110
+ attr_accessor :before_d, :after_d, :before_u, :after_u, :after_commit, :before_return
105
111
 
106
112
  before_destroy :set_before
107
113
  after_destroy :set_after
108
114
  before_update :set_before_update
109
115
  after_update :set_after_update
116
+ after_commit :set_after_commit, on: :destroy
110
117
 
111
118
  private
119
+
112
120
  def set_before
113
121
  @before_d = true
122
+ @before_return
114
123
  end
115
124
 
116
125
  def set_after
@@ -121,9 +130,16 @@ class ImmortalModel < ActiveRecord::Base
121
130
  @after_u = true
122
131
  end
123
132
 
133
+ def set_after_commit
134
+ @after_commit = true
135
+ end
136
+
124
137
  def set_before_update
125
138
  @before_u = true
126
139
  end
127
140
 
128
141
  end
129
142
 
143
+ class ImmortalNullableDeleted < ActiveRecord::Base
144
+ end
145
+
metadata CHANGED
@@ -1,51 +1,92 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: immortal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
5
- prerelease:
4
+ version: 2.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jordi Romero
9
8
  - Saimon Moore
9
+ - Pau Ramon
10
+ - Carlos Saura
11
+ - Andres Bravo
12
+ - Fran Casas
13
+ - Pau Perez
10
14
  autorequire:
11
15
  bindir: bin
12
16
  cert_chain: []
13
- date: 2011-10-18 00:00:00.000000000 Z
17
+ date: 2016-11-24 00:00:00.000000000 Z
14
18
  dependencies:
15
19
  - !ruby/object:Gem::Dependency
16
20
  name: activerecord
17
- requirement: &70196367376140 !ruby/object:Gem::Requirement
18
- none: false
21
+ requirement: !ruby/object:Gem::Requirement
19
22
  requirements:
20
- - - ~>
23
+ - - "~>"
21
24
  - !ruby/object:Gem::Version
22
- version: 3.1.1
25
+ version: 4.0.0
23
26
  type: :runtime
24
27
  prerelease: false
25
- version_requirements: *70196367376140
28
+ version_requirements: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: 4.0.0
26
33
  - !ruby/object:Gem::Dependency
27
34
  name: rspec
28
- requirement: &70196367375660 !ruby/object:Gem::Requirement
29
- none: false
35
+ requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - ~>
37
+ - - "~>"
32
38
  - !ruby/object:Gem::Version
33
39
  version: 2.6.0
34
40
  type: :development
35
41
  prerelease: false
36
- version_requirements: *70196367375660
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 2.6.0
37
47
  - !ruby/object:Gem::Dependency
38
48
  name: sqlite3
39
- requirement: &70196367375280 !ruby/object:Gem::Requirement
40
- none: false
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: byebug
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
41
71
  requirements:
42
- - - ! '>='
72
+ - - ">="
43
73
  - !ruby/object:Gem::Version
44
74
  version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '10.0'
45
82
  type: :development
46
83
  prerelease: false
47
- version_requirements: *70196367375280
48
- description: Typical paranoid gem built for Rails 3 and with the minimum code needed
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '10.0'
89
+ description: Typical paranoid gem built for Rails 4 and with the minimum code needed
49
90
  to satisfy acts_as_paranoid's API
50
91
  email:
51
92
  - jordi@jrom.net
@@ -54,9 +95,9 @@ executables: []
54
95
  extensions: []
55
96
  extra_rdoc_files: []
56
97
  files:
57
- - .gitignore
98
+ - ".gitignore"
58
99
  - Gemfile
59
- - Gemfile.lock
100
+ - LICENSE
60
101
  - README.md
61
102
  - Rakefile
62
103
  - immortal.gemspec
@@ -67,27 +108,27 @@ files:
67
108
  - spec/immortal_spec.rb
68
109
  - spec/spec_helper.rb
69
110
  homepage: http://github.com/teambox/immortal
70
- licenses: []
111
+ licenses:
112
+ - MIT
113
+ metadata: {}
71
114
  post_install_message:
72
115
  rdoc_options: []
73
116
  require_paths:
74
117
  - lib
75
118
  required_ruby_version: !ruby/object:Gem::Requirement
76
- none: false
77
119
  requirements:
78
- - - ! '>='
120
+ - - ">="
79
121
  - !ruby/object:Gem::Version
80
122
  version: '0'
81
123
  required_rubygems_version: !ruby/object:Gem::Requirement
82
- none: false
83
124
  requirements:
84
- - - ! '>='
125
+ - - ">="
85
126
  - !ruby/object:Gem::Version
86
127
  version: '0'
87
128
  requirements: []
88
129
  rubyforge_project:
89
- rubygems_version: 1.8.10
130
+ rubygems_version: 2.4.5.1
90
131
  signing_key:
91
- specification_version: 3
92
- summary: Replacement for acts_as_paranoid for Rails 3
132
+ specification_version: 4
133
+ summary: Replacement for acts_as_paranoid for Rails 4
93
134
  test_files: []
@@ -1,43 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- immortal (1.0.3)
5
- activerecord (~> 3.1.1)
6
-
7
- GEM
8
- remote: http://rubygems.org/
9
- specs:
10
- activemodel (3.1.1)
11
- activesupport (= 3.1.1)
12
- builder (~> 3.0.0)
13
- i18n (~> 0.6)
14
- activerecord (3.1.1)
15
- activemodel (= 3.1.1)
16
- activesupport (= 3.1.1)
17
- arel (~> 2.2.1)
18
- tzinfo (~> 0.3.29)
19
- activesupport (3.1.1)
20
- multi_json (~> 1.0)
21
- arel (2.2.1)
22
- builder (3.0.0)
23
- diff-lcs (1.1.3)
24
- i18n (0.6.0)
25
- multi_json (1.0.3)
26
- rspec (2.6.0)
27
- rspec-core (~> 2.6.0)
28
- rspec-expectations (~> 2.6.0)
29
- rspec-mocks (~> 2.6.0)
30
- rspec-core (2.6.4)
31
- rspec-expectations (2.6.0)
32
- diff-lcs (~> 1.1.2)
33
- rspec-mocks (2.6.0)
34
- sqlite3 (1.3.4)
35
- tzinfo (0.3.30)
36
-
37
- PLATFORMS
38
- ruby
39
-
40
- DEPENDENCIES
41
- immortal!
42
- rspec (~> 2.6.0)
43
- sqlite3