permanent_records 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|