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 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,3 @@
1
+ require 'acts_as_indestructible'
2
+ require 'fixture'
3
+ ActiveRecord::Base.send(:include, ActiveRecord::Acts::Indestructible)
@@ -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
+