ryanlowe-acts_as_indestructible 0.1.1
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/CHANGELOG +40 -0
- data/MIT-LICENSE +49 -0
- data/README +59 -0
- data/Rakefile +10 -0
- data/acts_as_indestructible.gemspec +17 -0
- data/init.rb +3 -0
- data/lib/acts_as_indestructible.rb +120 -0
- data/lib/fixture.rb +17 -0
- metadata +70 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
== 0.1.1
|
3
|
+
|
4
|
+
May 26
|
5
|
+
= test destroy_all with conditions
|
6
|
+
|
7
|
+
== 0.1.0
|
8
|
+
|
9
|
+
May 26
|
10
|
+
= add GitHub gemspec file
|
11
|
+
|
12
|
+
May 23
|
13
|
+
= divide the unit tests into subdirectories
|
14
|
+
= support find by id
|
15
|
+
|
16
|
+
May 22
|
17
|
+
= support for exists? and with :include_destroy option
|
18
|
+
|
19
|
+
May 15
|
20
|
+
= destroy and destroy_all: check that user is not nil and has an id method
|
21
|
+
= require user parameter for destroy and destroy_all methods
|
22
|
+
= prefix test models with Indestructible to avoid name collisions with popular model names
|
23
|
+
|
24
|
+
May 14
|
25
|
+
= add options_excluding_deleted protected method
|
26
|
+
|
27
|
+
May 2
|
28
|
+
= don't allow self methods delete or delete_all to be called
|
29
|
+
= test destroy_all
|
30
|
+
= don't destroy if already destroyed
|
31
|
+
= naively implement destroy instance method
|
32
|
+
= add Comment model
|
33
|
+
|
34
|
+
May 1 2008
|
35
|
+
= implement destroyed? instance method
|
36
|
+
= acts_as_indestructible declaration working
|
37
|
+
= add Post model
|
38
|
+
= add partial Rails skeleton to help with testing
|
39
|
+
= basic plugin project skeleton
|
40
|
+
= started project
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
Copyright (c) 2008 Ryan Lowe
|
2
|
+
|
3
|
+
http://ryanlowe.ca
|
4
|
+
http://disruptiveagility.com
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
|
25
|
+
===
|
26
|
+
|
27
|
+
Based on ideas from acts_as_paranoid
|
28
|
+
http://rubyforge.org/projects/ar-paranoid/
|
29
|
+
|
30
|
+
Copyright (c) 2005 Rick Olson
|
31
|
+
|
32
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
33
|
+
a copy of this software and associated documentation files (the
|
34
|
+
"Software"), to deal in the Software without restriction, including
|
35
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
36
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
37
|
+
permit persons to whom the Software is furnished to do so, subject to
|
38
|
+
the following conditions:
|
39
|
+
|
40
|
+
The above copyright notice and this permission notice shall be
|
41
|
+
included in all copies or substantial portions of the Software.
|
42
|
+
|
43
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
44
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
45
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
46
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
47
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
48
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
49
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
IMPORTANT: This plugin is a work in progress and should not be used in production
|
2
|
+
yet. Feel free to fork on GitHub and send patches.
|
3
|
+
|
4
|
+
If you would like to see your patch in this Git repository it must be tested.
|
5
|
+
If you find a bug, a test exposing the bug would be great.
|
6
|
+
|
7
|
+
= acts_as_indestructible
|
8
|
+
|
9
|
+
acts_as_indestructible aims to be an alternate version
|
10
|
+
of the acts_as_paranoid plugin idea, which is to mark ActiveRecord objects
|
11
|
+
as destroyed instead of actually deleting them from the database.
|
12
|
+
|
13
|
+
After an object is marked as destroyed it should be excluded from
|
14
|
+
all of the ActiveRecord method calls and act as if it
|
15
|
+
was deleted from the database.
|
16
|
+
|
17
|
+
= Differences from acts_as_paranoid
|
18
|
+
|
19
|
+
1. acts_as_indestructible fills the destroyed_at field as well
|
20
|
+
as destroyed_by
|
21
|
+
|
22
|
+
2. destroy() and destroy_all(conditions=nil) have a
|
23
|
+
user parameter, making them destroy(user) and
|
24
|
+
destroy_all(user,conditions=nil). The user
|
25
|
+
parameter is an ActiveRecord user object and
|
26
|
+
the user.id is stored in the destroyed_by column.
|
27
|
+
|
28
|
+
3. acts_as_paranoid overrides protected and private
|
29
|
+
ActiveRecord::Base methods which could change at any time.
|
30
|
+
acts_as_indestructible will work to provide the
|
31
|
+
same function while using the public API contract that
|
32
|
+
will not change within major Rails versions.
|
33
|
+
|
34
|
+
4. delete() and delete_all() throw exceptions and are effectively
|
35
|
+
deprecated, which prevents developers from permanently deleting
|
36
|
+
objects this way. Raw SQL could still delete objects permanently.
|
37
|
+
|
38
|
+
|
39
|
+
= API changes from ActiveRecord::Base
|
40
|
+
|
41
|
+
destroy(user)
|
42
|
+
destroy_all(user, conditions = nil)
|
43
|
+
|
44
|
+
exists?(id_or_conditions, options = {})
|
45
|
+
|
46
|
+
DEPRECATED:
|
47
|
+
|
48
|
+
ActiveRecord::Base.delete(id)
|
49
|
+
ActiveRecord::Base.delete_all
|
50
|
+
|
51
|
+
|
52
|
+
= Major plugin goals
|
53
|
+
|
54
|
+
- test all corner cases of the ActiveRecord methods affected by this plugin
|
55
|
+
- not impact performance, when possible
|
56
|
+
- play well with other major plugins
|
57
|
+
|
58
|
+
Also see TODO for specific things left to do
|
59
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
|
+
|
4
|
+
require(File.join(File.dirname(__FILE__), 'config', 'boot'))
|
5
|
+
|
6
|
+
require 'rake'
|
7
|
+
require 'rake/testtask'
|
8
|
+
require 'rake/rdoctask'
|
9
|
+
|
10
|
+
require 'tasks/rails'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "acts_as_indestructible"
|
3
|
+
s.version = "0.1.1"
|
4
|
+
s.date = "2008-05-26"
|
5
|
+
s.summary = "Mark objects as destroyed instead of deleting them from the database for Ruby on Rails ActiveRecord"
|
6
|
+
s.email = "rails@ryanlowe.ca"
|
7
|
+
s.homepage = "http://github.com/ryanlowe/acts_as_indestructible"
|
8
|
+
s.description = "Mark objects as destroyed instead of deleting them from the database for Ruby on Rails ActiveRecord"
|
9
|
+
s.has_rdoc = false
|
10
|
+
s.authors = ["Ryan Lowe"]
|
11
|
+
s.files = ["README", "CHANGELOG", "MIT-LICENSE", "Rakefile", "acts_as_indestructible.gemspec", "init.rb",
|
12
|
+
"lib/acts_as_indestructible.rb","lib/fixture.rb"]
|
13
|
+
s.test_files = []
|
14
|
+
s.rdoc_options = ["--main", "README"]
|
15
|
+
s.extra_rdoc_files = ["README","CHANGELOG"]
|
16
|
+
s.add_dependency("rails", ["> 2.0.0"])
|
17
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
module ActiveRecord #:nodoc:
|
2
|
+
|
3
|
+
class Base
|
4
|
+
#TODO: there must be a better place to put this
|
5
|
+
alias_method :super_reload, :reload
|
6
|
+
end
|
7
|
+
|
8
|
+
module Acts #:nodoc:
|
9
|
+
module Indestructible #:nodoc:
|
10
|
+
|
11
|
+
def self.included(base)
|
12
|
+
base.extend(ClassMethods)
|
13
|
+
class << base
|
14
|
+
alias_method :super_calculate, :calculate
|
15
|
+
alias_method :super_exists?, :exists?
|
16
|
+
alias_method :super_find, :find
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
|
22
|
+
def acts_as_indestructible(options = {})
|
23
|
+
extend ActiveRecord::Acts::Indestructible::SingletonMethods
|
24
|
+
include ActiveRecord::Acts::Indestructible::InstanceMethods
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
module SingletonMethods
|
30
|
+
|
31
|
+
def destroy_all(user, conditions = nil)
|
32
|
+
find(:all, :conditions => conditions).each { |object| object.destroy(user) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def delete(id)
|
36
|
+
raise "Is not allowed"
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete_all(conditions = nil)
|
40
|
+
raise "Is not allowed"
|
41
|
+
end
|
42
|
+
|
43
|
+
def calculate(operation, column_name, options = {})
|
44
|
+
super_calculate(operation, column_name, options_excluding_destroyed(options))
|
45
|
+
end
|
46
|
+
|
47
|
+
def exists?(id_or_conditions, options = {})
|
48
|
+
include_destroyed = options[:include_destroyed]
|
49
|
+
if id_or_conditions.is_a?(Hash)
|
50
|
+
include_destroyed = id_or_conditions[:include_destroyed]
|
51
|
+
id_or_conditions.delete :include_destroyed
|
52
|
+
end
|
53
|
+
options = {}
|
54
|
+
options[:select] = "#{quoted_table_name}.#{primary_key}"
|
55
|
+
options[:conditions] = expand_id_conditions(id_or_conditions) # private method; possibly fragile
|
56
|
+
options[:include_destroyed] = include_destroyed
|
57
|
+
!find(:first, options).nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
def find(*args)
|
61
|
+
options = args.extract_options!
|
62
|
+
include_destroyed = options[:include_destroyed]
|
63
|
+
return super_find(*args) if include_destroyed # revert to normal behaviour
|
64
|
+
options.delete :include_destroyed
|
65
|
+
args << options_excluding_destroyed(options)
|
66
|
+
super_find(*args)
|
67
|
+
end
|
68
|
+
|
69
|
+
#protected
|
70
|
+
|
71
|
+
# if they are protected class methods they cannot be unit tested? :(
|
72
|
+
|
73
|
+
def destroyed_condition
|
74
|
+
"#{quoted_table_name}.destroyed_at IS NULL"
|
75
|
+
end
|
76
|
+
|
77
|
+
def options_excluding_destroyed(options)
|
78
|
+
options = Hash.new if options.nil?
|
79
|
+
if options.has_key?(:conditions) and !options[:conditions].nil?
|
80
|
+
case options[:conditions]
|
81
|
+
when Array
|
82
|
+
options[:conditions][0] = destroyed_condition+" AND "+options[:conditions][0]
|
83
|
+
when Hash
|
84
|
+
options[:conditions][:destroyed_at] = nil
|
85
|
+
else
|
86
|
+
options[:conditions] = destroyed_condition+" AND "+options[:conditions]
|
87
|
+
end
|
88
|
+
else
|
89
|
+
options[:conditions] = destroyed_condition
|
90
|
+
end
|
91
|
+
options
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
module InstanceMethods
|
97
|
+
|
98
|
+
def destroyed?
|
99
|
+
!self[:destroyed_at].nil?
|
100
|
+
end
|
101
|
+
|
102
|
+
def destroy(user)
|
103
|
+
return if user.nil? or !user.is_a? ActiveRecord::Base # ...more conditions?
|
104
|
+
return if destroyed?
|
105
|
+
self[:destroyed_at] = Time.now
|
106
|
+
self[:destroyed_by] = user.id
|
107
|
+
save
|
108
|
+
end
|
109
|
+
|
110
|
+
def reload(options = nil)
|
111
|
+
options = {} if options.nil?
|
112
|
+
options[:include_destroyed] = true
|
113
|
+
super_reload(options)
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/lib/fixture.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class Fixture
|
2
|
+
|
3
|
+
#TODO: this is fragile
|
4
|
+
def find
|
5
|
+
klass = @class_name.is_a?(Class) ? @class_name : Object.const_get(@class_name) rescue nil
|
6
|
+
if klass
|
7
|
+
if klass.respond_to? :destroyed_condition
|
8
|
+
klass.find(self[klass.primary_key], :include_destroyed => true)
|
9
|
+
else # bad workaround! before the framework is loaded
|
10
|
+
klass.find(self[klass.primary_key])
|
11
|
+
end
|
12
|
+
else
|
13
|
+
raise FixtureClassNotFound, "The class #{@class_name.inspect} was not found."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ryanlowe-acts_as_indestructible
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Lowe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-05-26 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.0.0
|
23
|
+
version:
|
24
|
+
description: Mark objects as destroyed instead of deleting them from the database for Ruby on Rails ActiveRecord
|
25
|
+
email: rails@ryanlowe.ca
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
- CHANGELOG
|
33
|
+
files:
|
34
|
+
- README
|
35
|
+
- CHANGELOG
|
36
|
+
- MIT-LICENSE
|
37
|
+
- Rakefile
|
38
|
+
- acts_as_indestructible.gemspec
|
39
|
+
- init.rb
|
40
|
+
- lib/acts_as_indestructible.rb
|
41
|
+
- lib/fixture.rb
|
42
|
+
has_rdoc: false
|
43
|
+
homepage: http://github.com/ryanlowe/acts_as_indestructible
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options:
|
46
|
+
- --main
|
47
|
+
- README
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
version:
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.0.1
|
66
|
+
signing_key:
|
67
|
+
specification_version: 2
|
68
|
+
summary: Mark objects as destroyed instead of deleting them from the database for Ruby on Rails ActiveRecord
|
69
|
+
test_files: []
|
70
|
+
|