acts_as_paranoid 0.4.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57c69c6d7676bda21b0f8da016bd556f77003894
4
- data.tar.gz: 5293e8a3b417fecdfe117aefddcd8e2a0d2f4b09
3
+ metadata.gz: 59510a8af45d737dccea2ee97aa62553790c49a2
4
+ data.tar.gz: d9b52994074e903a7b9d7f4d88f5113d37039f12
5
5
  SHA512:
6
- metadata.gz: 8ae49e59c2f487c80243bb42c4d6e33c4f1676ecd0d039ba420c1e1e49e02b83a4c6635515d1ef53dd4ba0c68ebce427b386ce684992d4139ef2e4c638f61dd5
7
- data.tar.gz: f449a10feae541515688ed6c55446aa815025982f293a2375c44ec74b68a8cfe7928abc1dffee3758a868bca4d6d92eb13632642bb0dc40279d47e5973a7bfb0
6
+ metadata.gz: 75b9853cab16dbce9e96a8976b0337e01fce18b38273e087ec68c39eae4fe3b4d2b347f1ead9f147226db2bced977eee5c4ae5a87658208737ae8ec9bd8e7d25
7
+ data.tar.gz: 3f6f6a1337fe18092b37f84de3bb08740ab971fa55cb7fb9cb5d7db5551275d498079f8ba38b6cf282e069d529fb0bd32e6765fc364b71dbca23dab90e542d42
data/README.md CHANGED
@@ -1,10 +1,16 @@
1
1
  # ActsAsParanoid
2
2
 
3
- [![Build Status](https://travis-ci.org/ActsAsParanoid/acts_as_paranoid.png?branch=0-4-stable)](https://travis-ci.org/ActsAsParanoid/acts_as_paranoid)
3
+ [![Build Status](https://travis-ci.org/ActsAsParanoid/acts_as_paranoid.png?branch=master)](https://travis-ci.org/ActsAsParanoid/acts_as_paranoid)
4
4
 
5
- A simple plugin which hides records instead of deleting them, being able to recover them.
5
+ A Rails plugin to add soft delete.
6
6
 
7
- **This branch targets Rails 3.2.** If you're working with another version, switch to the corresponding branch.
7
+ This gem can be used to hide records instead of deleting them, making them recoverable later.
8
+
9
+ ## Support
10
+
11
+ **This branch targets Rails 4.x. and 5.x**
12
+
13
+ If you're working with another version, switch to the corresponding branch, or require an older version of the `acts_as_paranoid` gem.
8
14
 
9
15
  ## Usage
10
16
 
@@ -31,12 +37,18 @@ The values shown are the defaults. While *column* can be anything (as long as it
31
37
 
32
38
  If your column type is a `string`, you can also specify which value to use when marking an object as deleted by passing `:deleted_value` (default is "deleted"). Any records with a non-matching value in this column will be treated normally (ie: not deleted).
33
39
 
40
+ If your column type is a `boolean`, it is possible to specify `allow_nulls` option which is `true` by default. When set to `false`, entities that have `false` value in this column will be considered not deleted, and those which have `true` will be considered deleted. When `true` everything that has a not-null value will be considered deleted.
41
+
34
42
  ### Filtering
35
43
 
36
- If a record is deleted by ActsAsParanoid, it won't be retrieved when accessing the database. So, `Paranoiac.all` will **not** include the deleted_records. if you want to access them, you have 2 choices:
44
+ If a record is deleted by ActsAsParanoid, it won't be retrieved when accessing the database.
45
+
46
+ So, `Paranoiac.all` will **not** include the **deleted records**.
47
+
48
+ When you want to access them, you have 2 choices:
37
49
 
38
50
  ```ruby
39
- Paranoiac.only_deleted # retrieves the deleted records
51
+ Paranoiac.only_deleted # retrieves only the deleted records
40
52
  Paranoiac.with_deleted # retrieves all records, deleted or not
41
53
  ```
42
54
 
@@ -61,7 +73,13 @@ paranoiac.destroy!
61
73
  Paranoiac.delete_all!(conditions)
62
74
  ```
63
75
 
64
- You can also permanently delete a record by calling `destroy` or `delete_all` on it **twice**. If a record was already deleted (hidden by ActsAsParanoid) and you delete it again, it will be removed from the database. Take this example:
76
+ You can also permanently delete a record by calling `destroy_fully!` on the object.
77
+
78
+ Alternatively you can permanently delete a record by calling `destroy` or `delete_all` on the object **twice**.
79
+
80
+ If a record was already deleted (hidden by `ActsAsParanoid`) and you delete it again, it will be removed from the database.
81
+
82
+ Take this example:
65
83
 
66
84
  ```ruby
67
85
  p = Paranoiac.first
@@ -77,7 +95,9 @@ Recovery is easy. Just invoke `recover` on it, like this:
77
95
  Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover
78
96
  ```
79
97
 
80
- All associations marked as `:dependent => :destroy` are also recursively recovered. If you would like to disable this behavior, you can call `recover` with the `recursive` option:
98
+ All associations marked as `:dependent => :destroy` are also recursively recovered.
99
+
100
+ If you would like to disable this behavior, you can call `recover` with the `recursive` option:
81
101
 
82
102
  ```ruby
83
103
  Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover(:recursive => false)
@@ -91,7 +111,13 @@ class Paranoiac < ActiveRecord::Base
91
111
  end
92
112
  ```
93
113
 
94
- By default, dependent records will be recovered if they were deleted within 2 minutes of the object upon which they depend. This restores the objects to the state before the recursive deletion without restoring other objects that were deleted earlier. The behavior is only available when both parent and dependant are using timestamp fields to mark deletion, which is the default behavior. This window can be changed with the `dependent_recovery_window` option:
114
+ By default, dependent records will be recovered if they were deleted within 2 minutes of the object upon which they depend.
115
+
116
+ This restores the objects to the state before the recursive deletion without restoring other objects that were deleted earlier.
117
+
118
+ The behavior is only available when both parent and dependant are using timestamp fields to mark deletion, which is the default behavior.
119
+
120
+ This window can be changed with the `dependent_recovery_window` option:
95
121
 
96
122
  ```ruby
97
123
  class Paranoiac < ActiveRecord::Base
@@ -119,9 +145,9 @@ ActiveRecord's built-in uniqueness validation does not account for records delet
119
145
 
120
146
  ```ruby
121
147
  class Paranoiac < ActiveRecord::Base
122
- acts_as_paranoid
123
- validates_as_paranoid
124
- validates_uniqueness_of_without_deleted :name
148
+ acts_as_paranoid
149
+ validates_as_paranoid
150
+ validates_uniqueness_of_without_deleted :name
125
151
  end
126
152
 
127
153
  p1 = Paranoiac.create(:name => 'foo')
@@ -144,13 +170,15 @@ Paranoiac.with_deleted.first.deleted? #=> true
144
170
 
145
171
  ### Scopes
146
172
 
147
- As you've probably guessed, `with_deleted` and `only_deleted` are scopes. You can, however, chain them freely with other scopes you might have. This
173
+ As you've probably guessed, `with_deleted` and `only_deleted` are scopes. You can, however, chain them freely with other scopes you might have.
174
+
175
+ For example:
148
176
 
149
177
  ```ruby
150
178
  Paranoiac.pretty.with_deleted
151
179
  ```
152
180
 
153
- is exactly the same as
181
+ This is exactly the same as:
154
182
 
155
183
  ```ruby
156
184
  Paranoiac.with_deleted.pretty
@@ -160,8 +188,8 @@ You can work freely with scopes and it will just work:
160
188
 
161
189
  ```ruby
162
190
  class Paranoiac < ActiveRecord::Base
163
- acts_as_paranoid
164
- scope :pretty, where(:pretty => true)
191
+ acts_as_paranoid
192
+ scope :pretty, where(:pretty => true)
165
193
  end
166
194
 
167
195
  Paranoiac.create(:pretty => true)
@@ -179,7 +207,9 @@ Paranoiac.pretty.only_deleted.count #=> 1
179
207
 
180
208
  ### Associations
181
209
 
182
- Associations are also supported. From the simplest behaviors you'd expect to more nifty things like the ones mentioned previously or the usage of the `:with_deleted` option with `belongs_to`
210
+ Associations are also supported.
211
+
212
+ From the simplest behaviors you'd expect to more nifty things like the ones mentioned previously or the usage of the `:with_deleted` option with `belongs_to`
183
213
 
184
214
  ```ruby
185
215
  class Parent < ActiveRecord::Base
@@ -191,7 +221,7 @@ class ParanoiacChild < ActiveRecord::Base
191
221
  belongs_to :parent
192
222
 
193
223
  # You may need to provide a foreign_key like this
194
- belongs_to :parent_including_deleted, :class_name => "Parent", foreign_key => 'parent_id', :with_deleted => true
224
+ belongs_to :parent_including_deleted, :class_name => "Parent", :foreign_key => 'parent_id', :with_deleted => true
195
225
  end
196
226
 
197
227
  parent = Parent.first
@@ -212,32 +242,9 @@ Watch out for these caveats:
212
242
  - You cannot name association `*_with_deleted`
213
243
  - `unscoped` will return all records, deleted or not
214
244
 
215
- # Support
216
-
217
- This gem supports the most recent versions of Rails and Ruby.
218
-
219
- ## Rails
220
-
221
- For Rails 3.2 check the README at the [rails3.2](https://github.com/goncalossilva/rails3_acts_as_paranoid/tree/rails3.2) branch and add this to your Gemfile:
222
-
223
- gem "acts_as_paranoid", "~> 0.4.0"
224
-
225
- For Rails 3.1 check the README at the [rails3.1](https://github.com/goncalossilva/rails3_acts_as_paranoid/tree/rails3.1) branch and add this to your Gemfile:
226
-
227
- gem "rails3_acts_as_paranoid", "~>0.1.4"
228
-
229
- For Rails 3.0 check the README at the [rails3.0](https://github.com/goncalossilva/rails3_acts_as_paranoid/tree/rails3.0) branch and add this to your Gemfile:
230
-
231
- gem "rails3_acts_as_paranoid", "~>0.0.9"
232
-
233
-
234
- ## Ruby
235
-
236
- This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode).
237
-
238
-
239
245
  # Acknowledgements
240
246
 
247
+ * To [Rick Olson](https://github.com/technoweenie) for creating acts_as_paranoid
241
248
  * To [cheerfulstoic](https://github.com/cheerfulstoic) for adding recursive recovery
242
249
  * To [Jonathan Vaught](https://github.com/gravelpup) for adding paranoid validations
243
250
  * To [Geoffrey Hichborn](https://github.com/phene) for improving the overral code quality and adding support for after_commit
@@ -245,12 +252,9 @@ This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode).
245
252
  * To [vikramdhillon](https://github.com/vikramdhillon) for the idea and initial implementation of support for string column type
246
253
  * To [Craig Walker](https://github.com/softcraft-development) for Rails 3.1 support and fixing various pending issues
247
254
  * To [Charles G.](https://github.com/chuckg) for Rails 3.2 support and for making a desperately needed global code refactoring
255
+ * To [Gonçalo Silva](https://github.com/goncalossilva) for supporting this gem prior to v0.4.3
256
+ * To [Jean Boussier](https://github.com/byroot) for initial Rails 4.0.0 support
257
+ * To [Matijs van Zuijlen](https://github.com/mvz) for Rails 4.1 and 4.2 support
258
+ * To [Andrey Ponomarenko](https://github.com/sjke) for Rails 5 support
248
259
 
249
- ## Credits
250
-
251
- This plugin was inspired by [acts_as_paranoid](http://github.com/technoweenie/acts_as_paranoid) and [acts_as_active](http://github.com/fernandoluizao/acts_as_active).
252
-
253
- While porting it to Rails 3, I decided to apply the ideas behind those plugins to an unified solution while removing a **lot** of the complexity found in them. I eventually ended up writing a new plugin from scratch.
254
-
255
-
256
- Copyright © 2014 Zachary Scott, Gonçalo Silva, Rick Olson, released under the MIT license
260
+ See `LICENSE`.
@@ -8,12 +8,17 @@ module ActsAsParanoid
8
8
  end
9
9
 
10
10
  module ClassMethods
11
- def belongs_to_with_deleted(target, options = {})
12
- with_deleted = options.delete(:with_deleted)
13
- result = belongs_to_without_deleted(target, options)
11
+ def belongs_to_with_deleted(target, scope = nil, options = {})
12
+ with_deleted = (scope.is_a?(Hash) ? scope : options).delete(:with_deleted)
13
+ result = belongs_to_without_deleted(target, scope, options)
14
14
 
15
15
  if with_deleted
16
- result.options[:with_deleted] = with_deleted
16
+ if result.is_a? Hash
17
+ result.values.last.options[:with_deleted] = with_deleted
18
+ else
19
+ result.options[:with_deleted] = with_deleted
20
+ end
21
+
17
22
  unless method_defined? "#{target}_with_unscoped"
18
23
  class_eval <<-RUBY, __FILE__, __LINE__
19
24
  def #{target}_with_unscoped(*args)
@@ -23,9 +23,11 @@ module ActsAsParanoid
23
23
 
24
24
  def only_deleted
25
25
  if string_type_with_deleted_value?
26
- without_paranoid_default_scope.where("#{paranoid_column_reference} IS ?", paranoid_configuration[:deleted_value])
26
+ without_paranoid_default_scope.where(paranoid_column_reference => paranoid_configuration[:deleted_value])
27
+ elsif boolean_type_not_nullable?
28
+ without_paranoid_default_scope.where(paranoid_column_reference => true)
27
29
  else
28
- without_paranoid_default_scope.where("#{paranoid_column_reference} IS NOT ?", nil)
30
+ without_paranoid_default_scope.where.not(paranoid_column_reference => nil)
29
31
  end
30
32
  end
31
33
 
@@ -34,16 +36,17 @@ module ActsAsParanoid
34
36
  end
35
37
 
36
38
  def delete_all(conditions = nil)
37
- update_all ["#{paranoid_configuration[:column]} = ?", delete_now_value], conditions
39
+ where(conditions).update_all(["#{paranoid_configuration[:column]} = ?", delete_now_value])
38
40
  end
39
41
 
40
- def paranoid_default_scope_sql
42
+ def paranoid_default_scope
41
43
  if string_type_with_deleted_value?
42
- self.scoped.table[paranoid_column].eq(nil).
43
- or(self.scoped.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value])).
44
- to_sql
44
+ self.all.table[paranoid_column].eq(nil).
45
+ or(self.all.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value]))
46
+ elsif boolean_type_not_nullable?
47
+ self.all.table[paranoid_column].eq(false)
45
48
  else
46
- self.scoped.table[paranoid_column].eq(nil).to_sql
49
+ self.all.table[paranoid_column].eq(nil)
47
50
  end
48
51
  end
49
52
 
@@ -51,6 +54,10 @@ module ActsAsParanoid
51
54
  paranoid_column_type == :string && !paranoid_configuration[:deleted_value].nil?
52
55
  end
53
56
 
57
+ def boolean_type_not_nullable?
58
+ paranoid_column_type == :boolean && !paranoid_configuration[:allow_nulls]
59
+ end
60
+
54
61
  def paranoid_column
55
62
  paranoid_configuration[:column].to_sym
56
63
  end
@@ -74,8 +81,17 @@ module ActsAsParanoid
74
81
  protected
75
82
 
76
83
  def without_paranoid_default_scope
77
- scope = self.scoped.with_default_scope
78
- scope.where_values.delete(paranoid_default_scope_sql)
84
+ scope = self.all
85
+
86
+ if ActiveRecord::VERSION::MAJOR < 5
87
+ # ActiveRecord 4.0.*
88
+ scope = scope.with_default_scope if ActiveRecord::VERSION::MINOR < 1
89
+ scope.where_values.delete(paranoid_default_scope)
90
+ else
91
+ scope = scope.unscope(where: paranoid_default_scope)
92
+ # Fix problems with unscope group chain
93
+ scope = scope.unscoped if scope.to_sql.include? paranoid_default_scope.to_sql
94
+ end
79
95
 
80
96
  scope
81
97
  end
@@ -89,7 +105,7 @@ module ActsAsParanoid
89
105
  self.send(self.class.paranoid_column)
90
106
  end
91
107
 
92
- def destroy!
108
+ def destroy_fully!
93
109
  with_transaction_returning_status do
94
110
  run_callbacks :destroy do
95
111
  destroy_dependent_associations!
@@ -101,7 +117,7 @@ module ActsAsParanoid
101
117
  end
102
118
  end
103
119
 
104
- def destroy
120
+ def destroy!
105
121
  if !deleted?
106
122
  with_transaction_returning_status do
107
123
  run_callbacks :destroy do
@@ -112,10 +128,12 @@ module ActsAsParanoid
112
128
  end
113
129
  end
114
130
  else
115
- destroy!
131
+ destroy_fully!
116
132
  end
117
133
  end
118
134
 
135
+ alias_method :destroy, :destroy!
136
+
119
137
  def recover(options={})
120
138
  options = {
121
139
  :recursive => self.class.paranoid_configuration[:recover_dependent_associations],
@@ -144,7 +162,7 @@ module ActsAsParanoid
144
162
  # We can only recover by window if both parent and dependant have a
145
163
  # paranoid column type of :time.
146
164
  if self.class.paranoid_column_type == :time && klass.paranoid_column_type == :time
147
- scope = scope.merge(klass.deleted_inside_time_window(paranoid_value, window))
165
+ scope = scope.deleted_inside_time_window(paranoid_value, window)
148
166
  end
149
167
 
150
168
  scope.each do |object|
@@ -169,8 +187,13 @@ module ActsAsParanoid
169
187
  end
170
188
 
171
189
  def deleted?
172
- !(paranoid_value.nil? ||
173
- (self.class.string_type_with_deleted_value? && paranoid_value != self.class.delete_now_value))
190
+ !if self.class.string_type_with_deleted_value?
191
+ paranoid_value != self.class.delete_now_value || paranoid_value.nil?
192
+ elsif self.class.boolean_type_not_nullable?
193
+ paranoid_value == false
194
+ else
195
+ paranoid_value.nil?
196
+ end
174
197
  end
175
198
 
176
199
  alias_method :destroyed?, :deleted?
@@ -0,0 +1,15 @@
1
+ module ActsAsParanoid
2
+ module PreloaderAssociation
3
+ def self.included(base)
4
+ base.class_eval do
5
+ def build_scope_with_deleted
6
+ scope = build_scope_without_deleted
7
+ scope = scope.with_deleted if options[:with_deleted] && klass.respond_to?(:with_deleted)
8
+ scope
9
+ end
10
+
11
+ alias_method_chain :build_scope, :deleted
12
+ end
13
+ end
14
+ end
15
+ end
@@ -21,7 +21,7 @@ module ActsAsParanoid
21
21
 
22
22
  def delete_all(conditions = nil)
23
23
  if paranoid?
24
- update_all(paranoid_deletion_attributes, conditions)
24
+ where(conditions).update_all(paranoid_deletion_attributes)
25
25
  else
26
26
  delete_all!(conditions)
27
27
  end
@@ -6,37 +6,76 @@ module ActsAsParanoid
6
6
  base.extend ClassMethods
7
7
  end
8
8
 
9
- class UniquenessWithoutDeletedValidator < ActiveRecord::Validations::UniquenessValidator
10
- def validate_each(record, attribute, value)
11
- finder_class = find_finder_class_for(record)
12
- table = finder_class.arel_table
9
+ class UniquenessWithoutDeletedValidator
10
+ def self.[](version)
11
+ version = version.to_s
12
+ name = "V#{version.tr('.', '_')}"
13
+ unless constants.include? name.to_sym
14
+ raise "Unknown validator version #{version.inspect}; expected one of #{constants.sort.join(', ')}"
15
+ end
16
+ const_get name
17
+ end
13
18
 
14
- coder = record.class.serialized_attributes[attribute.to_s]
19
+ class V5 < ActiveRecord::Validations::UniquenessValidator
20
+ def validate_each(record, attribute, value)
21
+ finder_class = find_finder_class_for(record)
22
+ table = finder_class.arel_table
15
23
 
16
- if value && coder
17
- value = coder.dump value
18
- end
24
+ coder = record.class.attribute_types[attribute.to_s]
25
+ value = coder.type_cast_for_schema value if value && coder
19
26
 
20
- relation = build_relation(finder_class, table, attribute, value)
21
- [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value|
22
- relation = relation.and(table[pk_key.to_sym].not_eq(pk_value))
23
- end if record.persisted?
27
+ relation = build_relation(finder_class, table, attribute, value)
28
+ [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value|
29
+ relation = relation.where(table[pk_key.to_sym].not_eq(pk_value))
30
+ end if record.persisted?
24
31
 
25
- Array.wrap(options[:scope]).each do |scope_item|
26
- scope_value = record.send(scope_item)
27
- relation = relation.and(table[scope_item].eq(scope_value))
32
+ Array.wrap(options[:scope]).each do |scope_item|
33
+ relation = relation.where(table[scope_item].eq(record.public_send(scope_item)))
34
+ end
35
+
36
+ if relation.where(finder_class.paranoid_default_scope).where(relation).exists?
37
+ record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
38
+ end
28
39
  end
40
+ end
41
+
42
+ class V4 < ActiveRecord::Validations::UniquenessValidator
43
+ def validate_each(record, attribute, value)
44
+ finder_class = find_finder_class_for(record)
45
+ table = finder_class.arel_table
46
+
47
+ # TODO: Use record.class.column_types[attribute.to_s].coder ?
48
+ coder = record.class.column_types[attribute.to_s]
49
+
50
+ if value && coder
51
+ value = if coder.respond_to? :type_cast_for_database
52
+ coder.type_cast_for_database value
53
+ else
54
+ coder.type_cast_for_write value
55
+ end
56
+ end
57
+
58
+ relation = build_relation(finder_class, table, attribute, value)
59
+ [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value|
60
+ relation = relation.and(table[pk_key.to_sym].not_eq(pk_value))
61
+ end if record.persisted?
62
+
63
+ Array.wrap(options[:scope]).each do |scope_item|
64
+ scope_value = record.send(scope_item)
65
+ relation = relation.and(table[scope_item].eq(scope_value))
66
+ end
29
67
 
30
- # Re-add ActsAsParanoid default scope conditions manually.
31
- if finder_class.unscoped.where(finder_class.paranoid_default_scope_sql).where(relation).exists?
32
- record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
68
+ # Re-add ActsAsParanoid default scope conditions manually.
69
+ if finder_class.unscoped.where(finder_class.paranoid_default_scope).where(relation).exists?
70
+ record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
71
+ end
33
72
  end
34
73
  end
35
74
  end
36
75
 
37
76
  module ClassMethods
38
77
  def validates_uniqueness_of_without_deleted(*attr_names)
39
- validates_with UniquenessWithoutDeletedValidator, _merge_attributes(attr_names)
78
+ validates_with UniquenessWithoutDeletedValidator[ActiveRecord::VERSION::MAJOR], _merge_attributes(attr_names)
40
79
  end
41
80
  end
42
81
  end
@@ -1,3 +1,3 @@
1
1
  module ActsAsParanoid
2
- VERSION = "0.4.5"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -2,6 +2,7 @@ require 'acts_as_paranoid/core'
2
2
  require 'acts_as_paranoid/associations'
3
3
  require 'acts_as_paranoid/validations'
4
4
  require 'acts_as_paranoid/relation'
5
+ require 'acts_as_paranoid/preloader_association'
5
6
 
6
7
  module ActsAsParanoid
7
8
 
@@ -20,6 +21,7 @@ module ActsAsParanoid
20
21
 
21
22
  self.paranoid_configuration = { :column => "deleted_at", :column_type => "time", :recover_dependent_associations => true, :dependent_recovery_window => 2.minutes }
22
23
  self.paranoid_configuration.merge!({ :deleted_value => "deleted" }) if options[:column_type] == "string"
24
+ self.paranoid_configuration.merge!({ :allow_nulls => true }) if options[:column_type] == "boolean"
23
25
  self.paranoid_configuration.merge!(options) # user options
24
26
 
25
27
  raise ArgumentError, "'time', 'boolean' or 'string' expected for :column_type option, got #{paranoid_configuration[:column_type]}" unless ['time', 'boolean', 'string'].include? paranoid_configuration[:column_type]
@@ -31,7 +33,7 @@ module ActsAsParanoid
31
33
  include ActsAsParanoid::Core
32
34
 
33
35
  # Magic!
34
- default_scope { where(paranoid_default_scope_sql) }
36
+ default_scope { where(paranoid_default_scope) }
35
37
 
36
38
  if paranoid_configuration[:column_type] == 'time'
37
39
  scope :deleted_inside_time_window, lambda {|time, window|
@@ -55,3 +57,6 @@ ActiveRecord::Relation.send :include, ActsAsParanoid::Relation
55
57
 
56
58
  # Push the recover callback onto the activerecord callback list
57
59
  ActiveRecord::Callbacks::CALLBACKS.push(:before_recover, :after_recover)
60
+
61
+ # Use with_deleted in preloader build_scope
62
+ ActiveRecord::Associations::Preloader::Association.send :include, ActsAsParanoid::PreloaderAssociation
@@ -2,8 +2,6 @@ require 'test_helper'
2
2
 
3
3
  class AssociationsTest < ParanoidBaseTest
4
4
  def test_removal_with_associations
5
- # This test shows that the current implementation doesn't handle
6
- # assciation deletion correctly (when hard deleting via parent-object)
7
5
  paranoid_company_1 = ParanoidDestroyCompany.create! :name => "ParanoidDestroyCompany #1"
8
6
  paranoid_company_2 = ParanoidDeleteCompany.create! :name => "ParanoidDestroyCompany #1"
9
7
  paranoid_company_1.paranoid_products.create! :name => "ParanoidProduct #1"
@@ -19,19 +17,32 @@ class AssociationsTest < ParanoidBaseTest
19
17
  assert_equal 1, ParanoidDestroyCompany.with_deleted.count
20
18
  assert_equal 2, ParanoidProduct.with_deleted.count
21
19
 
22
- ParanoidDestroyCompany.with_deleted.first.destroy!
20
+ ParanoidDestroyCompany.with_deleted.first.destroy
23
21
  assert_equal 0, ParanoidDestroyCompany.count
24
22
  assert_equal 1, ParanoidProduct.count
25
23
  assert_equal 0, ParanoidDestroyCompany.with_deleted.count
26
24
  assert_equal 1, ParanoidProduct.with_deleted.count
27
25
 
28
- ParanoidDeleteCompany.with_deleted.first.destroy!
26
+ ParanoidDeleteCompany.first.destroy
27
+ assert_equal 0, ParanoidDeleteCompany.count
28
+ assert_equal 0, ParanoidProduct.count
29
+ assert_equal 1, ParanoidDeleteCompany.with_deleted.count
30
+ assert_equal 1, ParanoidProduct.with_deleted.count
31
+
32
+ ParanoidDeleteCompany.with_deleted.first.destroy
29
33
  assert_equal 0, ParanoidDeleteCompany.count
30
34
  assert_equal 0, ParanoidProduct.count
31
35
  assert_equal 0, ParanoidDeleteCompany.with_deleted.count
32
36
  assert_equal 0, ParanoidProduct.with_deleted.count
33
37
  end
34
38
 
39
+ def test_belongs_to_with_scope_option
40
+ paranoid_has_many_dependant = ParanoidHasManyDependant.new
41
+ includes_values = ParanoidTime.includes(:not_paranoid).includes_values
42
+
43
+ assert_equal includes_values, paranoid_has_many_dependant.association(:paranoid_time_with_scope).scope.includes_values
44
+ end
45
+
35
46
  def test_belongs_to_with_deleted
36
47
  paranoid_time = ParanoidTime.first
37
48
  paranoid_has_many_dependant = paranoid_time.paranoid_has_many_dependants.create(:name => 'dependant!')
@@ -72,19 +83,19 @@ class AssociationsTest < ParanoidBaseTest
72
83
  end
73
84
 
74
85
  def test_belongs_to_options
75
- paranoid_time = ParanoidHasManyDependant.reflections[:paranoid_time]
86
+ paranoid_time = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time]
76
87
  assert_equal :belongs_to, paranoid_time.macro
77
88
  assert_nil paranoid_time.options[:with_deleted]
78
89
  end
79
90
 
80
91
  def test_belongs_to_with_deleted_options
81
- paranoid_time_with_deleted = ParanoidHasManyDependant.reflections[:paranoid_time_with_deleted]
92
+ paranoid_time_with_deleted = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time_with_deleted]
82
93
  assert_equal :belongs_to, paranoid_time_with_deleted.macro
83
94
  assert paranoid_time_with_deleted.options[:with_deleted]
84
95
  end
85
96
 
86
97
  def test_belongs_to_polymorphic_with_deleted_options
87
- paranoid_time_polymorphic_with_deleted = ParanoidHasManyDependant.reflections[:paranoid_time_polymorphic_with_deleted]
98
+ paranoid_time_polymorphic_with_deleted = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time_polymorphic_with_deleted]
88
99
  assert_equal :belongs_to, paranoid_time_polymorphic_with_deleted.macro
89
100
  assert paranoid_time_polymorphic_with_deleted.options[:with_deleted]
90
101
  end
@@ -101,6 +112,9 @@ class AssociationsTest < ParanoidBaseTest
101
112
  child.destroy
102
113
  assert_paranoid_deletion(child)
103
114
 
115
+ parent.reload
116
+
117
+ assert_equal [], parent.paranoid_has_many_dependants.to_a
104
118
  assert_equal [child], parent.paranoid_has_many_dependants.with_deleted.to_a
105
119
  end
106
120
 
data/test/test_core.rb CHANGED
@@ -4,7 +4,6 @@ class ParanoidTest < ParanoidBaseTest
4
4
  def test_paranoid?
5
5
  assert !NotParanoid.paranoid?
6
6
  assert_raise(NoMethodError) { NotParanoid.delete_all! }
7
- assert_raise(NoMethodError) { NotParanoid.first.destroy! }
8
7
  assert_raise(NoMethodError) { NotParanoid.with_deleted }
9
8
  assert_raise(NoMethodError) { NotParanoid.only_deleted }
10
9
 
@@ -41,9 +40,9 @@ class ParanoidTest < ParanoidBaseTest
41
40
  end
42
41
 
43
42
  def test_real_removal
44
- ParanoidTime.first.destroy!
43
+ ParanoidTime.first.destroy_fully!
45
44
  ParanoidBoolean.delete_all!("name = 'extremely paranoid' OR name = 'really paranoid'")
46
- ParanoidString.first.destroy!
45
+ ParanoidString.first.destroy_fully!
47
46
  assert_equal 2, ParanoidTime.count
48
47
  assert_equal 1, ParanoidBoolean.count
49
48
  assert_equal 0, ParanoidString.count
@@ -60,7 +59,7 @@ class ParanoidTest < ParanoidBaseTest
60
59
 
61
60
  ParanoidTime.delete_all!
62
61
  assert_empty ParanoidTime.all
63
- assert_empty ParanoidTime.with_deleted.all
62
+ assert_empty ParanoidTime.with_deleted
64
63
  end
65
64
 
66
65
  def test_non_persisted_destroy
@@ -77,6 +76,10 @@ class ParanoidTest < ParanoidBaseTest
77
76
  assert_not_nil pt.paranoid_value
78
77
  end
79
78
 
79
+ def test_removal_not_persisted
80
+ assert ParanoidTime.new.destroy
81
+ end
82
+
80
83
  def test_recovery
81
84
  assert_equal 3, ParanoidBoolean.count
82
85
  ParanoidBoolean.first.destroy
@@ -141,12 +144,18 @@ class ParanoidTest < ParanoidBaseTest
141
144
  assert_equal 0, ParanoidHasOneDependant.count
142
145
  assert_equal 1, NotParanoid.count
143
146
  assert_equal 0, HasOneNotParanoid.count
147
+
148
+ assert_equal 3, ParanoidTime.with_deleted.count
149
+ assert_equal 4, ParanoidHasManyDependant.with_deleted.count
150
+ assert_equal 3, ParanoidBelongsDependant.with_deleted.count
151
+ assert_equal @paranoid_boolean_count + 3, ParanoidBoolean.with_deleted.count
152
+ assert_equal 3, ParanoidHasOneDependant.with_deleted.count
144
153
  end
145
154
 
146
155
  def test_recursive_real_removal
147
156
  setup_recursive_tests
148
157
 
149
- @paranoid_time_object.destroy!
158
+ @paranoid_time_object.destroy_fully!
150
159
 
151
160
  assert_equal 0, ParanoidTime.only_deleted.count
152
161
  assert_equal 1, ParanoidHasManyDependant.only_deleted.count
@@ -295,8 +304,8 @@ class ParanoidTest < ParanoidBaseTest
295
304
  @paranoid_with_callback.recover
296
305
  end
297
306
 
298
- assert @paranoid_with_callback.called_before_recover
299
- assert @paranoid_with_callback.called_after_recover
307
+ assert @paranoid_with_callback.called_before_recover
308
+ assert @paranoid_with_callback.called_after_recover
300
309
  end
301
310
 
302
311
  def test_delete_by_multiple_id_is_paranoid
@@ -384,4 +393,44 @@ class ParanoidTest < ParanoidBaseTest
384
393
  2.times { ps.destroy }
385
394
  assert_equal 0, ParanoidString.with_deleted.where(:id => ps).count
386
395
  end
396
+
397
+ # Test boolean type columns, that are not nullable
398
+ def test_boolean_type_with_no_nil_value_before_destroy
399
+ ps = ParanoidBooleanNotNullable.create!()
400
+ assert_equal 1, ParanoidBooleanNotNullable.where(:id => ps).count
401
+ end
402
+
403
+ def test_boolean_type_with_no_nil_value_after_destroy
404
+ ps = ParanoidBooleanNotNullable.create!()
405
+ ps.destroy
406
+ assert_equal 0, ParanoidBooleanNotNullable.where(:id => ps).count
407
+ end
408
+
409
+ def test_boolean_type_with_no_nil_value_before_destroy_with_deleted
410
+ ps = ParanoidBooleanNotNullable.create!()
411
+ assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
412
+ end
413
+
414
+ def test_boolean_type_with_no_nil_value_after_destroy_with_deleted
415
+ ps = ParanoidBooleanNotNullable.create!()
416
+ ps.destroy
417
+ assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
418
+ end
419
+
420
+ def test_boolean_type_with_no_nil_value_before_destroy_only_deleted
421
+ ps = ParanoidBooleanNotNullable.create!()
422
+ assert_equal 0, ParanoidBooleanNotNullable.only_deleted.where(:id => ps).count
423
+ end
424
+
425
+ def test_boolean_type_with_no_nil_value_after_destroy_only_deleted
426
+ ps = ParanoidBooleanNotNullable.create!()
427
+ ps.destroy
428
+ assert_equal 1, ParanoidBooleanNotNullable.only_deleted.where(:id => ps).count
429
+ end
430
+
431
+ def test_boolean_type_with_no_nil_value_after_destroyed_twice
432
+ ps = ParanoidBooleanNotNullable.create!()
433
+ 2.times { ps.destroy }
434
+ assert_equal 0, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
435
+ end
387
436
  end
@@ -37,7 +37,7 @@ class MultipleDefaultScopesTest < ParanoidBaseTest
37
37
  assert_equal 0, ParanoidHuman.only_deleted.count
38
38
  assert_equal 3, ParanoidHuman.unscoped.count
39
39
 
40
- ParanoidHuman.first.destroy!
40
+ ParanoidHuman.first.destroy_fully!
41
41
  assert_equal 1, ParanoidHuman.count
42
42
  assert_equal 1, ParanoidHuman.with_deleted.count
43
43
  assert_equal 0, ParanoidHuman.only_deleted.count
data/test/test_helper.rb CHANGED
@@ -24,7 +24,7 @@ def setup_db
24
24
  t.integer :paranoid_belongs_dependant_id
25
25
  t.integer :not_paranoid_id
26
26
 
27
- t.timestamps
27
+ timestamps t
28
28
  end
29
29
 
30
30
  create_table :paranoid_booleans do |t|
@@ -32,7 +32,7 @@ def setup_db
32
32
  t.boolean :is_deleted
33
33
  t.integer :paranoid_time_id
34
34
 
35
- t.timestamps
35
+ timestamps t
36
36
  end
37
37
 
38
38
  create_table :paranoid_strings do |t|
@@ -44,14 +44,14 @@ def setup_db
44
44
  t.string :name
45
45
  t.integer :paranoid_time_id
46
46
 
47
- t.timestamps
47
+ timestamps t
48
48
  end
49
49
 
50
50
  create_table :has_one_not_paranoids do |t|
51
51
  t.string :name
52
52
  t.integer :paranoid_time_id
53
53
 
54
- t.timestamps
54
+ timestamps t
55
55
  end
56
56
 
57
57
  create_table :paranoid_has_many_dependants do |t|
@@ -61,14 +61,14 @@ def setup_db
61
61
  t.string :paranoid_time_polymorphic_with_deleted_type
62
62
  t.integer :paranoid_belongs_dependant_id
63
63
 
64
- t.timestamps
64
+ timestamps t
65
65
  end
66
66
 
67
67
  create_table :paranoid_belongs_dependants do |t|
68
68
  t.string :name
69
69
  t.datetime :deleted_at
70
70
 
71
- t.timestamps
71
+ timestamps t
72
72
  end
73
73
 
74
74
  create_table :paranoid_has_one_dependants do |t|
@@ -76,28 +76,28 @@ def setup_db
76
76
  t.datetime :deleted_at
77
77
  t.integer :paranoid_boolean_id
78
78
 
79
- t.timestamps
79
+ timestamps t
80
80
  end
81
81
 
82
82
  create_table :paranoid_with_callbacks do |t|
83
83
  t.string :name
84
84
  t.datetime :deleted_at
85
85
 
86
- t.timestamps
86
+ timestamps t
87
87
  end
88
88
 
89
89
  create_table :paranoid_destroy_companies do |t|
90
90
  t.string :name
91
91
  t.datetime :deleted_at
92
92
 
93
- t.timestamps
93
+ timestamps t
94
94
  end
95
95
 
96
96
  create_table :paranoid_delete_companies do |t|
97
97
  t.string :name
98
98
  t.datetime :deleted_at
99
99
 
100
- t.timestamps
100
+ timestamps t
101
101
  end
102
102
 
103
103
  create_table :paranoid_products do |t|
@@ -106,46 +106,46 @@ def setup_db
106
106
  t.string :name
107
107
  t.datetime :deleted_at
108
108
 
109
- t.timestamps
109
+ timestamps t
110
110
  end
111
111
 
112
112
  create_table :super_paranoids do |t|
113
113
  t.string :type
114
- t.references :has_many_inherited_super_paranoidz
114
+ t.references :has_many_inherited_super_paranoidz, index: { name: 'index__sp_id_on_has_many_isp' }
115
115
  t.datetime :deleted_at
116
116
 
117
- t.timestamps
117
+ timestamps t
118
118
  end
119
119
 
120
120
  create_table :has_many_inherited_super_paranoidzs do |t|
121
- t.references :super_paranoidz
121
+ t.references :super_paranoidz, index: { name: 'index_has_many_isp_on_sp_id' }
122
122
  t.datetime :deleted_at
123
123
 
124
- t.timestamps
124
+ timestamps t
125
125
  end
126
126
 
127
127
  create_table :paranoid_many_many_parent_lefts do |t|
128
128
  t.string :name
129
- t.timestamps
129
+ timestamps t
130
130
  end
131
131
 
132
132
  create_table :paranoid_many_many_parent_rights do |t|
133
133
  t.string :name
134
- t.timestamps
134
+ timestamps t
135
135
  end
136
136
 
137
137
  create_table :paranoid_many_many_children do |t|
138
138
  t.integer :paranoid_many_many_parent_left_id
139
139
  t.integer :paranoid_many_many_parent_right_id
140
140
  t.datetime :deleted_at
141
- t.timestamps
141
+ timestamps t
142
142
  end
143
143
 
144
144
  create_table :paranoid_with_scoped_validations do |t|
145
145
  t.string :name
146
146
  t.string :category
147
147
  t.datetime :deleted_at
148
- t.timestamps
148
+ timestamps t
149
149
  end
150
150
 
151
151
  create_table :paranoid_forests do |t|
@@ -153,7 +153,7 @@ def setup_db
153
153
  t.boolean :rainforest
154
154
  t.datetime :deleted_at
155
155
 
156
- t.timestamps
156
+ timestamps t
157
157
  end
158
158
 
159
159
  create_table :paranoid_trees do |t|
@@ -161,14 +161,14 @@ def setup_db
161
161
  t.string :name
162
162
  t.datetime :deleted_at
163
163
 
164
- t.timestamps
164
+ timestamps t
165
165
  end
166
166
 
167
167
  create_table :paranoid_humen do |t|
168
168
  t.string :gender
169
169
  t.datetime :deleted_at
170
170
 
171
- t.timestamps
171
+ timestamps t
172
172
  end
173
173
 
174
174
  create_table :paranoid_androids do |t|
@@ -181,13 +181,48 @@ def setup_db
181
181
  t.string :paranoid_thing_type
182
182
  t.datetime :deleted_at
183
183
  end
184
+
185
+ create_table :paranoid_boolean_not_nullables do |t|
186
+ t.string :name
187
+ t.boolean :deleted, :boolean, :null => false, :default => false
188
+ end
189
+
190
+ create_table :paranoid_belongs_to_polymorphics do |t|
191
+ t.string :name
192
+ t.string :parent_type
193
+ t.integer :parent_id
194
+ t.datetime :deleted_at
195
+
196
+ t.timestamps
197
+ end
198
+
199
+ create_table :not_paranoid_has_many_as_parents do |t|
200
+ t.string :name
201
+
202
+ t.timestamps
203
+ end
204
+
205
+ create_table :paranoid_has_many_as_parents do |t|
206
+ t.string :name
207
+ t.datetime :deleted_at
208
+
209
+ t.timestamps
210
+ end
184
211
  end
185
212
  end
186
213
 
214
+ def timestamps(table)
215
+ table.column :created_at , :timestamp, :null => false
216
+ table.column :updated_at , :timestamp, :null => false
217
+ end
218
+
187
219
  def teardown_db
188
- ActiveRecord::Base.connection.tables.each do |table|
189
- ActiveRecord::Base.connection.drop_table(table)
220
+ tables = if ActiveRecord::VERSION::MAJOR < 5
221
+ ActiveRecord::Base.connection.tables
222
+ else
223
+ ActiveRecord::Base.connection.data_sources
190
224
  end
225
+ tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
191
226
  end
192
227
 
193
228
  class ParanoidTime < ActiveRecord::Base
@@ -233,6 +268,7 @@ end
233
268
  class ParanoidHasManyDependant < ActiveRecord::Base
234
269
  acts_as_paranoid
235
270
  belongs_to :paranoid_time
271
+ belongs_to :paranoid_time_with_scope, -> { includes(:not_paranoid) }, :class_name => 'ParanoidTime', :foreign_key => :paranoid_time_id
236
272
  belongs_to :paranoid_time_with_deleted, :class_name => 'ParanoidTime', :foreign_key => :paranoid_time_id, :with_deleted => true
237
273
  belongs_to :paranoid_time_polymorphic_with_deleted, :class_name => 'ParanoidTime', :foreign_key => :paranoid_time_id, :polymorphic => true, :with_deleted => true
238
274
 
@@ -323,25 +359,6 @@ class InheritedParanoid < SuperParanoid
323
359
  acts_as_paranoid
324
360
  end
325
361
 
326
- class ParanoidObserver < ActiveRecord::Observer
327
- observe :paranoid_with_callback
328
-
329
- attr_accessor :called_before_recover, :called_after_recover
330
-
331
- def before_recover(paranoid_object)
332
- self.called_before_recover = paranoid_object
333
- end
334
-
335
- def after_recover(paranoid_object)
336
- self.called_after_recover = paranoid_object
337
- end
338
-
339
- def reset
340
- self.called_before_recover = nil
341
- self.called_after_recover = nil
342
- end
343
- end
344
-
345
362
 
346
363
  class ParanoidManyManyParentLeft < ActiveRecord::Base
347
364
  has_many :paranoid_many_many_children
@@ -364,7 +381,19 @@ class ParanoidWithScopedValidation < ActiveRecord::Base
364
381
  validates_uniqueness_of :name, :scope => :category
365
382
  end
366
383
 
367
- ParanoidWithCallback.add_observer(ParanoidObserver.instance)
384
+ class ParanoidBelongsToPolymorphic < ActiveRecord::Base
385
+ acts_as_paranoid
386
+ belongs_to :parent, :polymorphic => true, :with_deleted => true
387
+ end
388
+
389
+ class NotParanoidHasManyAsParent < ActiveRecord::Base
390
+ has_many :paranoid_belongs_to_polymorphics, :as => :parent, :dependent => :destroy
391
+ end
392
+
393
+ class ParanoidHasManyAsParent < ActiveRecord::Base
394
+ acts_as_paranoid
395
+ has_many :paranoid_belongs_to_polymorphics, :as => :parent, :dependent => :destroy
396
+ end
368
397
 
369
398
  class ParanoidBaseTest < ActiveSupport::TestCase
370
399
  def setup
@@ -378,8 +407,6 @@ class ParanoidBaseTest < ActiveSupport::TestCase
378
407
  ParanoidString.create! :name => "strings can be paranoid"
379
408
  NotParanoid.create! :name => "no paranoid goals"
380
409
  ParanoidWithCallback.create! :name => "paranoid with callbacks"
381
-
382
- ParanoidObserver.instance.reset
383
410
  end
384
411
 
385
412
  def teardown
@@ -411,11 +438,9 @@ end
411
438
  class ParanoidForest < ActiveRecord::Base
412
439
  acts_as_paranoid
413
440
 
414
- # HACK: scope throws an error on 1.8.7 because the logger isn't initialized (see https://github.com/Casecommons/pg_search/issues/26)
415
- require "active_support/core_ext/logger.rb"
416
441
  ActiveRecord::Base.logger = Logger.new(StringIO.new)
417
442
 
418
- scope :rainforest, where(:rainforest => true)
443
+ scope :rainforest, lambda{ where(:rainforest => true) }
419
444
 
420
445
  has_many :paranoid_trees, :dependent => :destroy
421
446
  end
@@ -428,7 +453,7 @@ end
428
453
 
429
454
  class ParanoidHuman < ActiveRecord::Base
430
455
  acts_as_paranoid
431
- default_scope where('gender = ?', 'male')
456
+ default_scope { where('gender = ?', 'male') }
432
457
  end
433
458
 
434
459
  class ParanoidAndroid < ActiveRecord::Base
@@ -440,3 +465,8 @@ class ParanoidSection < ActiveRecord::Base
440
465
  belongs_to :paranoid_time
441
466
  belongs_to :paranoid_thing, :polymorphic => true, :dependent => :destroy
442
467
  end
468
+
469
+ class ParanoidBooleanNotNullable < ActiveRecord::Base
470
+ acts_as_paranoid column: 'deleted', column_type: 'boolean', allow_nulls: false
471
+ end
472
+
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ class PreloaderAssociationTest < ParanoidBaseTest
4
+ def test_includes_with_deleted
5
+ paranoid_time = ParanoidTime.first
6
+ paranoid_has_many_dependant = paranoid_time.paranoid_has_many_dependants.create(:name => 'dependant!')
7
+
8
+ paranoid_time.destroy
9
+
10
+ ParanoidHasManyDependant.with_deleted.includes(:paranoid_time_with_deleted).each do |hasmany|
11
+ assert_not_nil hasmany.paranoid_time_with_deleted
12
+ end
13
+ end
14
+
15
+ def test_includes_with_deleted_with_polymorphic_parent
16
+ not_paranoid_parent = NotParanoidHasManyAsParent.create(name: 'not paranoid parent')
17
+ paranoid_parent = ParanoidHasManyAsParent.create(name: 'paranoid parent')
18
+ ParanoidBelongsToPolymorphic.create(:name => 'belongs_to', :parent => not_paranoid_parent)
19
+ ParanoidBelongsToPolymorphic.create(:name => 'belongs_to', :parent => paranoid_parent)
20
+
21
+ paranoid_parent.destroy
22
+
23
+ ParanoidBelongsToPolymorphic.with_deleted.includes(:parent).each do |hasmany|
24
+ assert_not_nil hasmany.parent
25
+ end
26
+ end
27
+ end
@@ -75,7 +75,7 @@ class RelationsTest < ParanoidBaseTest
75
75
 
76
76
  def test_fake_removal_through_relation
77
77
  # destroy: through a relation.
78
- ParanoidForest.rainforest.destroy(@paranoid_forest_3)
78
+ ParanoidForest.rainforest.destroy(@paranoid_forest_3.id)
79
79
  assert_equal 1, ParanoidForest.rainforest.count
80
80
  assert_equal 2, ParanoidForest.rainforest.with_deleted.count
81
81
  assert_equal 1, ParanoidForest.rainforest.only_deleted.count
@@ -95,8 +95,8 @@ class RelationsTest < ParanoidBaseTest
95
95
 
96
96
  # destroy: two-step through a relation
97
97
  paranoid_tree = @paranoid_forest_1.paranoid_trees.first
98
- @paranoid_forest_1.paranoid_trees.order(:id).destroy(paranoid_tree)
99
- @paranoid_forest_1.paranoid_trees.only_deleted.destroy(paranoid_tree)
98
+ @paranoid_forest_1.paranoid_trees.order(:id).destroy(paranoid_tree.id)
99
+ @paranoid_forest_1.paranoid_trees.only_deleted.destroy(paranoid_tree.id)
100
100
  assert_equal 1, @paranoid_forest_1.paranoid_trees(true).count
101
101
  assert_equal 1, @paranoid_forest_1.paranoid_trees(true).with_deleted.count
102
102
  assert_equal 0, @paranoid_forest_1.paranoid_trees(true).only_deleted.count
metadata CHANGED
@@ -1,33 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_paranoid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zachary Scott
8
- - André Medeiros
9
8
  - Goncalo Silva
10
- - Charles G.
11
9
  - Rick Olson
12
10
  autorequire:
13
11
  bindir: bin
14
12
  cert_chain: []
15
- date: 2016-07-09 00:00:00.000000000 Z
13
+ date: 2016-08-09 00:00:00.000000000 Z
16
14
  dependencies:
17
15
  - !ruby/object:Gem::Dependency
18
16
  name: activerecord
19
17
  requirement: !ruby/object:Gem::Requirement
20
18
  requirements:
21
- - - "~>"
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '4.0'
22
+ - - "<"
22
23
  - !ruby/object:Gem::Version
23
- version: '3.2'
24
+ version: '5.1'
24
25
  type: :runtime
25
26
  prerelease: false
26
27
  version_requirements: !ruby/object:Gem::Requirement
27
28
  requirements:
28
- - - "~>"
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: '4.0'
32
+ - - "<"
29
33
  - !ruby/object:Gem::Version
30
- version: '3.2'
34
+ version: '5.1'
35
+ - !ruby/object:Gem::Dependency
36
+ name: activesupport
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '4.0'
42
+ - - "<"
43
+ - !ruby/object:Gem::Version
44
+ version: '5.1'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '4.0'
52
+ - - "<"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.1'
31
55
  - !ruby/object:Gem::Dependency
32
56
  name: bundler
33
57
  requirement: !ruby/object:Gem::Requirement
@@ -74,16 +98,22 @@ dependencies:
74
98
  name: minitest
75
99
  requirement: !ruby/object:Gem::Requirement
76
100
  requirements:
77
- - - "~>"
101
+ - - ">="
78
102
  - !ruby/object:Gem::Version
79
103
  version: '4.0'
104
+ - - "<="
105
+ - !ruby/object:Gem::Version
106
+ version: '6.0'
80
107
  type: :development
81
108
  prerelease: false
82
109
  version_requirements: !ruby/object:Gem::Requirement
83
110
  requirements:
84
- - - "~>"
111
+ - - ">="
85
112
  - !ruby/object:Gem::Version
86
113
  version: '4.0'
114
+ - - "<="
115
+ - !ruby/object:Gem::Version
116
+ version: '6.0'
87
117
  description: Check the home page for more in-depth information.
88
118
  email:
89
119
  - e@zzak.io
@@ -96,6 +126,7 @@ files:
96
126
  - lib/acts_as_paranoid.rb
97
127
  - lib/acts_as_paranoid/associations.rb
98
128
  - lib/acts_as_paranoid/core.rb
129
+ - lib/acts_as_paranoid/preloader_association.rb
99
130
  - lib/acts_as_paranoid/relation.rb
100
131
  - lib/acts_as_paranoid/validations.rb
101
132
  - lib/acts_as_paranoid/version.rb
@@ -104,10 +135,10 @@ files:
104
135
  - test/test_default_scopes.rb
105
136
  - test/test_helper.rb
106
137
  - test/test_inheritance.rb
107
- - test/test_observers.rb
138
+ - test/test_preloader_association.rb
108
139
  - test/test_relations.rb
109
140
  - test/test_validations.rb
110
- homepage: https://github.com/zzak/acts_as_paranoid
141
+ homepage: https://github.com/ActsAsParanoid/acts_as_paranoid
111
142
  licenses:
112
143
  - MIT
113
144
  metadata: {}
@@ -134,7 +165,7 @@ summary: Active Record plugin which allows you to hide and restore records witho
134
165
  actually deleting them.
135
166
  test_files:
136
167
  - test/test_inheritance.rb
137
- - test/test_observers.rb
168
+ - test/test_preloader_association.rb
138
169
  - test/test_relations.rb
139
170
  - test/test_core.rb
140
171
  - test/test_validations.rb
@@ -1,16 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ParanoidObserverTest < ParanoidBaseTest
4
- def test_called_observer_methods
5
- @subject = ParanoidWithCallback.new
6
- @subject.save
7
-
8
- assert_nil ParanoidObserver.instance.called_before_recover
9
- assert_nil ParanoidObserver.instance.called_after_recover
10
-
11
- ParanoidWithCallback.find(@subject.id).recover
12
-
13
- assert_equal @subject, ParanoidObserver.instance.called_before_recover
14
- assert_equal @subject, ParanoidObserver.instance.called_after_recover
15
- end
16
- end