permanent_records 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +3 -0
- data/README.markdown +15 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/permanent_records.rb +121 -25
- data/permanent_records.gemspec +11 -12
- data/test/comment.rb +11 -0
- data/test/difficulty.rb +11 -0
- data/test/hole.rb +5 -0
- data/test/location.rb +5 -0
- data/test/permanent_records_test.rb +124 -3
- data/test/schema.rb +24 -0
- data/test/test_helper.rb +5 -0
- data/test/unused_model.rb +2 -0
- metadata +27 -14
data/Gemfile
ADDED
data/README.markdown
CHANGED
@@ -54,7 +54,22 @@ And if you had dependent records that were set to be destroyed along with the pa
|
|
54
54
|
# all the comments are destroyed as well
|
55
55
|
User.find(3).revive
|
56
56
|
# all the comments that were just destroyed are now back in pristine condition
|
57
|
+
|
58
|
+
# forcing deletion works the same way: fi you hard delete a record, its dependent records will also be hard deleted
|
57
59
|
|
60
|
+
## Can I use default scopes?
|
61
|
+
|
62
|
+
In Rails 3, yes.
|
63
|
+
|
64
|
+
default_scope where(:deleted_at => nil)
|
65
|
+
|
66
|
+
If you use such a default scope, you will need to simulate the `deleted` scope with a method
|
67
|
+
|
68
|
+
def self.deleted
|
69
|
+
self.unscoped.where('deleted_at IS NOT NULL')
|
70
|
+
end
|
71
|
+
|
72
|
+
Rails 2 provides no practical means of overriding default scopes (aside from using something like `Model.with_exclusive_scope { find(id) }`), so you'll need to implement those yourself if you need them.
|
58
73
|
|
59
74
|
Patches welcome, forks celebrated.
|
60
75
|
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ begin
|
|
9
9
|
gem.description = %Q{Never Lose Data. Rather than deleting rows this sets Record#deleted_at and gives you all the scopes you need to work with your data.}
|
10
10
|
gem.email = "gems@6brand.com"
|
11
11
|
gem.homepage = "http://github.com/JackDanger/permanent_records"
|
12
|
-
gem.authors = ["Jack Danger Canty"]
|
12
|
+
gem.authors = ["Jack Danger Canty", "David Sulc"]
|
13
13
|
end
|
14
14
|
rescue LoadError
|
15
15
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.1.0
|
data/lib/permanent_records.rb
CHANGED
@@ -75,42 +75,60 @@ module PermanentRecords
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def revive
|
78
|
-
|
79
|
-
if ActiveRecord::VERSION::MAJOR >= 3
|
78
|
+
if active_record_3?
|
80
79
|
_run_revive_callbacks do
|
81
80
|
set_deleted_at nil
|
82
81
|
end
|
83
82
|
else
|
84
83
|
run_callbacks :before_revive
|
84
|
+
attempt_notifying_observers(:before_revive)
|
85
85
|
set_deleted_at nil
|
86
86
|
run_callbacks :after_revive
|
87
|
+
attempt_notifying_observers(:after_revive)
|
87
88
|
end
|
88
89
|
self
|
89
90
|
end
|
90
|
-
|
91
|
-
def set_deleted_at(value)
|
92
|
-
return self unless is_permanent?
|
93
|
-
record = self.class.find(id)
|
94
|
-
record.update_attribute(:deleted_at, value)
|
95
|
-
@attributes, @attributes_cache = record.attributes, record.attributes
|
96
|
-
end
|
97
91
|
|
98
92
|
def destroy(force = nil)
|
99
|
-
if
|
100
|
-
|
93
|
+
if active_record_3?
|
94
|
+
unless is_permanent? && (:force != force)
|
95
|
+
return permanently_delete_records_after{ super() }
|
96
|
+
end
|
101
97
|
end
|
102
98
|
destroy_with_permanent_records force
|
103
99
|
end
|
100
|
+
|
101
|
+
private
|
102
|
+
def set_deleted_at(value)
|
103
|
+
return self unless is_permanent?
|
104
|
+
record = self.class
|
105
|
+
record = record.unscoped if active_record_3?
|
106
|
+
record = record.find(id)
|
107
|
+
record.deleted_at = value
|
108
|
+
begin
|
109
|
+
# we call save! instead of update_attribute so an ActiveRecord::RecordInvalid
|
110
|
+
# error will be raised if the record isn't valid. (This prevents reviving records that
|
111
|
+
# disregard validation constraints,)
|
112
|
+
record.save!
|
113
|
+
@attributes, @attributes_cache = record.attributes, record.attributes
|
114
|
+
rescue Exception => e
|
115
|
+
# trigger dependent record destruction (they were revived before this record,
|
116
|
+
# which cannot be revived due to validations)
|
117
|
+
record.destroy
|
118
|
+
raise e
|
119
|
+
end
|
120
|
+
end
|
104
121
|
|
105
122
|
def destroy_with_permanent_records(force = nil)
|
106
|
-
|
107
|
-
|
123
|
+
unless active_record_3?
|
124
|
+
unless is_permanent? && (:force != force)
|
125
|
+
return permanently_delete_records_after{ destroy_without_permanent_records }
|
126
|
+
end
|
108
127
|
end
|
109
128
|
unless deleted? || new_record?
|
110
129
|
set_deleted_at Time.now
|
111
130
|
end
|
112
|
-
|
113
|
-
if ActiveRecord::VERSION::MAJOR >= 3
|
131
|
+
if active_record_3?
|
114
132
|
_run_destroy_callbacks do
|
115
133
|
save
|
116
134
|
end
|
@@ -126,16 +144,29 @@ module PermanentRecords
|
|
126
144
|
self.class.reflections.select do |name, reflection|
|
127
145
|
'destroy' == reflection.options[:dependent].to_s && reflection.klass.is_permanent?
|
128
146
|
end.each do |name, reflection|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
147
|
+
cardinality = reflection.macro.to_s.gsub('has_', '')
|
148
|
+
if cardinality == 'many'
|
149
|
+
records = send(name)
|
150
|
+
records = records.unscoped if active_record_3?
|
151
|
+
records = records.find(:all,
|
152
|
+
:conditions => [
|
153
|
+
"#{reflection.quoted_table_name}.deleted_at > ?" +
|
154
|
+
" AND " +
|
155
|
+
"#{reflection.quoted_table_name}.deleted_at < ?",
|
156
|
+
deleted_at - 3.seconds,
|
157
|
+
deleted_at + 3.seconds
|
158
|
+
]
|
159
|
+
)
|
160
|
+
elsif cardinality == 'one'
|
161
|
+
if active_record_3?
|
162
|
+
self.class.unscoped do
|
163
|
+
records = [] << send(name)
|
164
|
+
end
|
165
|
+
else
|
166
|
+
records = [] << send(name)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
records.compact.each do |dependent|
|
139
170
|
dependent.revive
|
140
171
|
end
|
141
172
|
|
@@ -143,6 +174,71 @@ module PermanentRecords
|
|
143
174
|
send(name, :reload)
|
144
175
|
end
|
145
176
|
end
|
177
|
+
|
178
|
+
def attempt_notifying_observers(callback)
|
179
|
+
begin
|
180
|
+
notify_observers(callback)
|
181
|
+
rescue NoMethodError => e
|
182
|
+
# do nothing: this model isn't being observed
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# return the records corresponding to an association with the `:dependent => :destroy` option
|
187
|
+
def get_dependent_records
|
188
|
+
dependent_records = {}
|
189
|
+
|
190
|
+
# check which dependent records are to be destroyed
|
191
|
+
klass = self.class
|
192
|
+
klass.reflections.each do |key, reflection|
|
193
|
+
if reflection.options[:dependent] == :destroy
|
194
|
+
next unless records = self.send(key) # skip if there are no dependent record instances
|
195
|
+
if records.respond_to? :size
|
196
|
+
next unless records.size > 0 # skip if there are no dependent record instances
|
197
|
+
else
|
198
|
+
records = [] << records
|
199
|
+
end
|
200
|
+
dependent_record = records.first
|
201
|
+
next if dependent_record.nil?
|
202
|
+
dependent_records[dependent_record.class] = records.map(&:id)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
dependent_records
|
206
|
+
end
|
207
|
+
|
208
|
+
# If we force the destruction of the record, we will need to force the destruction of dependent records if the
|
209
|
+
# user specified `:dependent => :destroy` in the model.
|
210
|
+
# By default, the call to super/destroy_with_permanent_records (i.e. the &block param) will only soft delete
|
211
|
+
# the dependent records; we keep track of the dependent records
|
212
|
+
# that have `:dependent => :destroy` and call destroy(force) on them after the call to super
|
213
|
+
def permanently_delete_records_after(&block)
|
214
|
+
dependent_records = get_dependent_records
|
215
|
+
result = block.call
|
216
|
+
if result
|
217
|
+
permanently_delete_records(dependent_records)
|
218
|
+
end
|
219
|
+
result
|
220
|
+
end
|
221
|
+
|
222
|
+
# permanently delete the records (i.e. remove from database)
|
223
|
+
def permanently_delete_records(dependent_records)
|
224
|
+
dependent_records.each do |klass, ids|
|
225
|
+
ids.each do |id|
|
226
|
+
begin
|
227
|
+
record = klass
|
228
|
+
record = record.unscoped if active_record_3?
|
229
|
+
record = record.find(id)
|
230
|
+
rescue ActiveRecord::RecordNotFound
|
231
|
+
next # the record has already been deleted, possibly due to another association with `:dependent => :destroy`
|
232
|
+
end
|
233
|
+
record.deleted_at = nil
|
234
|
+
record.destroy(:force)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def active_record_3?
|
240
|
+
ActiveRecord::VERSION::MAJOR >= 3
|
241
|
+
end
|
146
242
|
end
|
147
243
|
end
|
148
244
|
|
data/permanent_records.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{permanent_records}
|
8
|
-
s.version = "2.
|
8
|
+
s.version = "2.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["Jack Danger Canty"]
|
12
|
-
s.date = %q{2011-
|
11
|
+
s.authors = ["Jack Danger Canty", "David Sulc"]
|
12
|
+
s.date = %q{2011-06-06}
|
13
13
|
s.description = %q{Never Lose Data. Rather than deleting rows this sets Record#deleted_at and gives you all the scopes you need to work with your data.}
|
14
14
|
s.email = %q{gems@6brand.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
|
+
"Gemfile",
|
21
22
|
"LICENSE",
|
22
23
|
"MIT-LICENSE",
|
23
24
|
"README.markdown",
|
@@ -27,37 +28,35 @@ Gem::Specification.new do |s|
|
|
27
28
|
"install.rb",
|
28
29
|
"lib/permanent_records.rb",
|
29
30
|
"permanent_records.gemspec",
|
31
|
+
"test/comment.rb",
|
30
32
|
"test/database.yml",
|
33
|
+
"test/difficulty.rb",
|
31
34
|
"test/hole.rb",
|
32
35
|
"test/kitty.rb",
|
36
|
+
"test/location.rb",
|
33
37
|
"test/mole.rb",
|
34
38
|
"test/muskrat.rb",
|
35
39
|
"test/permanent_records_test.rb",
|
36
40
|
"test/schema.rb",
|
37
41
|
"test/test_helper.rb",
|
42
|
+
"test/unused_model.rb",
|
38
43
|
"uninstall.rb"
|
39
44
|
]
|
40
45
|
s.homepage = %q{http://github.com/JackDanger/permanent_records}
|
41
46
|
s.require_paths = ["lib"]
|
42
47
|
s.rubygems_version = %q{1.4.2}
|
43
48
|
s.summary = %q{Soft-delete your ActiveRecord records}
|
44
|
-
s.test_files = [
|
45
|
-
"test/hole.rb",
|
46
|
-
"test/kitty.rb",
|
47
|
-
"test/mole.rb",
|
48
|
-
"test/muskrat.rb",
|
49
|
-
"test/permanent_records_test.rb",
|
50
|
-
"test/schema.rb",
|
51
|
-
"test/test_helper.rb"
|
52
|
-
]
|
53
49
|
|
54
50
|
if s.respond_to? :specification_version then
|
55
51
|
s.specification_version = 3
|
56
52
|
|
57
53
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
54
|
+
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
58
55
|
else
|
56
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
59
57
|
end
|
60
58
|
else
|
59
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
61
60
|
end
|
62
61
|
end
|
63
62
|
|
data/test/comment.rb
ADDED
data/test/difficulty.rb
ADDED
data/test/hole.rb
CHANGED
@@ -3,4 +3,9 @@ class Hole < ActiveRecord::Base
|
|
3
3
|
has_many :muskrats, :dependent => :destroy
|
4
4
|
# moles are not permanent
|
5
5
|
has_many :moles, :dependent => :destroy
|
6
|
+
|
7
|
+
has_one :location, :dependent => :destroy
|
8
|
+
has_one :unused_model, :dependent => :destroy
|
9
|
+
has_one :difficulty, :dependent => :destroy
|
10
|
+
has_many :comments, :dependent => :destroy
|
6
11
|
end
|
data/test/location.rb
ADDED
@@ -1,6 +1,11 @@
|
|
1
|
+
# note: functionality to deal with default scopes (and the `unscoped` scope) has been added (and will be tested) for Rails 3
|
2
|
+
# this default scope functionality is skipped for Rails 2, because Rails 2 provides no functional means of altering the default scope
|
3
|
+
# in particular, setting the default scope in Rails 3 to ignore soft deleted records will work properly, whereas in Rails 2, it will
|
4
|
+
# lead to a world of pain
|
5
|
+
|
1
6
|
require File.expand_path(File.dirname(__FILE__) + "/test_helper")
|
2
7
|
|
3
|
-
%w(hole mole muskrat kitty).each do |a|
|
8
|
+
%w(hole mole muskrat kitty location comment difficulty unused_model).each do |a|
|
4
9
|
require File.expand_path(File.dirname(__FILE__) + "/" + a)
|
5
10
|
end
|
6
11
|
|
@@ -17,7 +22,28 @@ class PermanentRecordsTest < ActiveSupport::TestCase
|
|
17
22
|
@hole = Hole.create(:number => 14)
|
18
23
|
@hole.muskrats.create(:name => "Active Muskrat")
|
19
24
|
@hole.muskrats.create(:name => "Deleted Muskrat", :deleted_at => 5.days.ago)
|
25
|
+
Location.delete_all
|
26
|
+
@location = Location.create(:name => "South wall")
|
27
|
+
@hole.location = @location
|
28
|
+
@hole.save!
|
20
29
|
@mole = @hole.moles.create(:name => "Grabowski")
|
30
|
+
|
31
|
+
if ActiveRecord::VERSION::MAJOR >= 3
|
32
|
+
Difficulty.unscoped.delete_all
|
33
|
+
Comment.unscoped.delete_all
|
34
|
+
else
|
35
|
+
Difficulty.delete_all
|
36
|
+
Comment.delete_all
|
37
|
+
end
|
38
|
+
# test has_one cardinality with model having a default scope
|
39
|
+
@hole_with_difficulty = Hole.create(:number => 16)
|
40
|
+
@hole_with_difficulty.difficulty = Difficulty.create!(:name => 'Hard')
|
41
|
+
@hole_with_difficulty.save!
|
42
|
+
|
43
|
+
# test has_many cardinality with model having a default scope
|
44
|
+
@hole_with_comments = Hole.create(:number => 16)
|
45
|
+
@hole_with_comments.comments << Comment.create!(:text => "Beware of the pond.")
|
46
|
+
@hole_with_comments.comments << Comment.create!(:text => "Muskrats live here.")
|
21
47
|
end
|
22
48
|
|
23
49
|
def teardown
|
@@ -109,7 +135,7 @@ class PermanentRecordsTest < ActiveSupport::TestCase
|
|
109
135
|
end
|
110
136
|
end
|
111
137
|
|
112
|
-
def
|
138
|
+
def test_dependent_permanent_records_with_has_many_cardinality_should_be_marked_as_deleted
|
113
139
|
assert @hole.is_permanent?
|
114
140
|
assert @hole.muskrats.first.is_permanent?
|
115
141
|
assert_no_difference "Muskrat.count" do
|
@@ -118,7 +144,17 @@ class PermanentRecordsTest < ActiveSupport::TestCase
|
|
118
144
|
assert @hole.muskrats.first.deleted?
|
119
145
|
end
|
120
146
|
|
121
|
-
def
|
147
|
+
def test_dependent_permanent_records_with_has_one_cardinality_should_be_marked_as_deleted
|
148
|
+
assert @hole.is_permanent?
|
149
|
+
assert @hole.location.is_permanent?
|
150
|
+
assert_no_difference "Location.count" do
|
151
|
+
@hole.destroy
|
152
|
+
end
|
153
|
+
assert @hole.location.deleted?
|
154
|
+
assert Location.find_by_name("South wall").deleted?
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_dependent_permanent_records_with_has_many_cardinality_should_be_revived_when_parent_is_revived
|
122
158
|
assert @hole.is_permanent?
|
123
159
|
@hole.destroy
|
124
160
|
assert @hole.muskrats.find_by_name("Active Muskrat").deleted?
|
@@ -126,6 +162,49 @@ class PermanentRecordsTest < ActiveSupport::TestCase
|
|
126
162
|
assert !@hole.muskrats.find_by_name("Active Muskrat").deleted?
|
127
163
|
end
|
128
164
|
|
165
|
+
def test_dependent_permanent_records_with_has_one_cardinality_should_be_revived_when_parent_is_revived
|
166
|
+
assert @hole.is_permanent?
|
167
|
+
@hole.destroy
|
168
|
+
assert Location.find_by_name("South wall").deleted?
|
169
|
+
@hole.revive
|
170
|
+
assert !Location.find_by_name("South wall").deleted?
|
171
|
+
end
|
172
|
+
|
173
|
+
# see comment at top of file for reasoning behind conditional testing of default scope
|
174
|
+
if ActiveRecord::VERSION::MAJOR >= 3
|
175
|
+
def test_dependent_permanent_records_with_has_one_cardinality_and_default_scope_should_be_revived_when_parent_is_revived
|
176
|
+
assert @hole_with_difficulty.is_permanent?
|
177
|
+
assert_difference("Difficulty.count", -1) do
|
178
|
+
@hole_with_difficulty.destroy
|
179
|
+
end
|
180
|
+
assert_nil Difficulty.find_by_name("Hard")
|
181
|
+
assert Difficulty.unscoped.find_by_name("Hard").deleted?
|
182
|
+
@hole_with_difficulty.revive
|
183
|
+
assert_not_nil Difficulty.find_by_name("Hard")
|
184
|
+
assert !Difficulty.unscoped.find_by_name("Hard").deleted?
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_dependent_permanent_records_with_has_many_cardinality_and_default_scope_should_be_revived_when_parent_is_revived
|
188
|
+
assert @hole_with_comments.is_permanent?
|
189
|
+
assert_difference("Comment.count", -2) do
|
190
|
+
@hole_with_comments.destroy
|
191
|
+
end
|
192
|
+
assert_nil Comment.find_by_text("Beware of the pond.")
|
193
|
+
assert Comment.unscoped.find_by_text("Beware of the pond.").deleted?
|
194
|
+
@hole_with_comments.revive
|
195
|
+
assert_not_nil Comment.find_by_text("Beware of the pond.")
|
196
|
+
assert !Comment.unscoped.find_by_text("Beware of the pond.").deleted?
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_inexistent_dependent_models_should_not_cause_errors
|
201
|
+
hole_with_unused_model = Hole.create!(:number => 1)
|
202
|
+
hole_with_unused_model.destroy
|
203
|
+
assert_nothing_raised do
|
204
|
+
hole_with_unused_model.revive
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
129
208
|
def test_old_dependent_permanent_records_should_not_be_revived
|
130
209
|
assert @hole.is_permanent?
|
131
210
|
@hole.destroy
|
@@ -133,4 +212,46 @@ class PermanentRecordsTest < ActiveSupport::TestCase
|
|
133
212
|
@hole.revive
|
134
213
|
assert @hole.muskrats.find_by_name("Deleted Muskrat").deleted?
|
135
214
|
end
|
215
|
+
|
216
|
+
def test_validate_records_before_revival
|
217
|
+
duplicate_location = Location.new(@location.attributes)
|
218
|
+
@location.destroy
|
219
|
+
@location.reload
|
220
|
+
duplicate_location.save!
|
221
|
+
assert_equal duplicate_location.name, @location.name
|
222
|
+
assert_no_difference('Location.not_deleted.count') do
|
223
|
+
assert_raise (ActiveRecord::RecordInvalid) do
|
224
|
+
@location.revive
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_force_deleting_a_record_with_has_one_force_deletes_dependent_records
|
230
|
+
hole = Hole.create(:number => 1)
|
231
|
+
location = Location.create(:name => "Near the clubhouse")
|
232
|
+
hole.location = location
|
233
|
+
hole.save!
|
234
|
+
|
235
|
+
assert_difference(monitor_for('Hole'), -1) do
|
236
|
+
assert_difference(monitor_for('Location'), -1) do
|
237
|
+
hole.destroy(:force)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def test_force_deleting_a_record_with_has_many_force_deletes_dependent_records
|
243
|
+
assert_difference(monitor_for('Hole'), -1) do
|
244
|
+
assert_difference(monitor_for('Comment'), -2) do
|
245
|
+
@hole_with_comments.destroy(:force)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_force_deletign_with_multiple_associations
|
251
|
+
assert_difference(monitor_for('Muskrat'), -2) do
|
252
|
+
assert_difference(monitor_for('Mole'), -1) do
|
253
|
+
@hole.destroy(:force)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
136
257
|
end
|
data/test/schema.rb
CHANGED
@@ -19,5 +19,29 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
19
19
|
t.string :name
|
20
20
|
t.references :hole
|
21
21
|
end
|
22
|
+
|
23
|
+
create_table :locations, :force => true do |t|
|
24
|
+
t.string :name
|
25
|
+
t.references :hole
|
26
|
+
t.datetime :deleted_at
|
27
|
+
end
|
28
|
+
|
29
|
+
create_table :comments, :force => true do |t|
|
30
|
+
t.string :text
|
31
|
+
t.references :hole
|
32
|
+
t.datetime :deleted_at
|
33
|
+
end
|
34
|
+
|
35
|
+
create_table :difficulties, :force => true do |t|
|
36
|
+
t.string :name
|
37
|
+
t.references :hole
|
38
|
+
t.datetime :deleted_at
|
39
|
+
end
|
40
|
+
|
41
|
+
create_table :unused_models, :force => true do |t|
|
42
|
+
t.string :name
|
43
|
+
t.references :hole
|
44
|
+
t.datetime :deleted_at
|
45
|
+
end
|
22
46
|
|
23
47
|
end
|
data/test/test_helper.rb
CHANGED
@@ -37,4 +37,9 @@ class ActiveSupport::TestCase #:nodoc:
|
|
37
37
|
self.use_instantiated_fixtures = false
|
38
38
|
|
39
39
|
# Add more helper methods to be used by all tests here...
|
40
|
+
def monitor_for(class_name)
|
41
|
+
result = class_name
|
42
|
+
result += '.unscoped' if ActiveRecord::VERSION::MAJOR >= 3
|
43
|
+
result += '.count'
|
44
|
+
end
|
40
45
|
end
|
metadata
CHANGED
@@ -1,24 +1,38 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: permanent_records
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 2.0.0
|
10
|
+
version: 2.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jack Danger Canty
|
14
|
+
- David Sulc
|
14
15
|
autorequire:
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2011-
|
19
|
+
date: 2011-06-06 00:00:00 -07:00
|
19
20
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
type: :runtime
|
24
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
requirement: *id001
|
34
|
+
prerelease: false
|
35
|
+
name: activerecord
|
22
36
|
description: Never Lose Data. Rather than deleting rows this sets Record#deleted_at and gives you all the scopes you need to work with your data.
|
23
37
|
email: gems@6brand.com
|
24
38
|
executables: []
|
@@ -30,6 +44,7 @@ extra_rdoc_files:
|
|
30
44
|
- README.markdown
|
31
45
|
files:
|
32
46
|
- .document
|
47
|
+
- Gemfile
|
33
48
|
- LICENSE
|
34
49
|
- MIT-LICENSE
|
35
50
|
- README.markdown
|
@@ -39,14 +54,18 @@ files:
|
|
39
54
|
- install.rb
|
40
55
|
- lib/permanent_records.rb
|
41
56
|
- permanent_records.gemspec
|
57
|
+
- test/comment.rb
|
42
58
|
- test/database.yml
|
59
|
+
- test/difficulty.rb
|
43
60
|
- test/hole.rb
|
44
61
|
- test/kitty.rb
|
62
|
+
- test/location.rb
|
45
63
|
- test/mole.rb
|
46
64
|
- test/muskrat.rb
|
47
65
|
- test/permanent_records_test.rb
|
48
66
|
- test/schema.rb
|
49
67
|
- test/test_helper.rb
|
68
|
+
- test/unused_model.rb
|
50
69
|
- uninstall.rb
|
51
70
|
has_rdoc: true
|
52
71
|
homepage: http://github.com/JackDanger/permanent_records
|
@@ -82,11 +101,5 @@ rubygems_version: 1.4.2
|
|
82
101
|
signing_key:
|
83
102
|
specification_version: 3
|
84
103
|
summary: Soft-delete your ActiveRecord records
|
85
|
-
test_files:
|
86
|
-
|
87
|
-
- test/kitty.rb
|
88
|
-
- test/mole.rb
|
89
|
-
- test/muskrat.rb
|
90
|
-
- test/permanent_records_test.rb
|
91
|
-
- test/schema.rb
|
92
|
-
- test/test_helper.rb
|
104
|
+
test_files: []
|
105
|
+
|