gravelpup-rails3_acts_as_paranoid 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Gonçalo Silva
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,56 @@
1
+ # ActsAsParanoid
2
+
3
+ A simple plugin which hides records instead of deleting them, being able to recover them.
4
+
5
+ ## Credits
6
+
7
+ 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).
8
+
9
+ 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.
10
+
11
+ ## Usage
12
+
13
+ You can enable ActsAsParanoid like this:
14
+
15
+ class Paranoiac < ActiveRecord::Base
16
+ acts_as_paranoid
17
+ end
18
+
19
+ ### Options
20
+
21
+ You can also specify the name of the column to store it's *deletion* and the type of data it holds:
22
+
23
+ - :column => 'deleted_at'
24
+ - :type => 'time'
25
+
26
+ The values shown are the defaults. While *column* can be anything (as long as it exists in your database), *type* is restricted to "boolean" or "time".
27
+
28
+ ### Filtering
29
+
30
+ 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:
31
+ Paranoiac.only_deleted # retrieves the deleted records
32
+ Paranoiac.with_deleted # retrieves all records, deleted or not
33
+
34
+ ### Real deletion
35
+
36
+ In order to really delete a record, just use:
37
+ paranoiac.destroy!
38
+ Paranoiac.delete_all!(conditions)
39
+
40
+ You can also definitively 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:
41
+ Paranoiac.first.destroy # does NOT delete the first record, just hides it
42
+ Paranoiac.only_deleted.destroy # deletes the first record from the database
43
+
44
+ ### Recovery
45
+
46
+ Recovery is easy. Just invoke `recover` on it, like this:
47
+ Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover
48
+
49
+ ## Caveats
50
+
51
+ Watch out for these caveats:
52
+
53
+ - If you use default\_scope in your model, you need to include it after the `acts_as_paranoid` invocation
54
+ - You cannot use scopes named `with_deleted` and `only_deleted`
55
+
56
+ Copyright © 2010 Gonçalo Silva, released under the MIT license
@@ -0,0 +1,71 @@
1
+ require 'active_record'
2
+ require 'validations/uniqueness_without_deleted'
3
+
4
+ module ActsAsParanoid
5
+ def acts_as_paranoid(options = {})
6
+ raise ArgumentError, "Hash expected, got #{options.class.name}" if not options.is_a?(Hash) and not options.empty?
7
+
8
+ configuration = { :column => "deleted_at", :column_type => "time" }
9
+ configuration.update(options) unless options.nil?
10
+
11
+ type = case configuration[:column_type]
12
+ when "time" then "Time.now"
13
+ when "boolean" then "true"
14
+ else
15
+ raise ArgumentError, "'time' or 'boolean' expected for :column_type option, got #{configuration[:column_type]}"
16
+ end
17
+
18
+ class_eval <<-EOV
19
+ default_scope where("#{self.table_name}.#{configuration[:column]} IS ?", nil)
20
+
21
+ class << self
22
+ def with_deleted
23
+ self.unscoped.where("") #self.unscoped.reload
24
+ end
25
+
26
+ def only_deleted
27
+ self.unscoped.where("#{self.table_name}.#{configuration[:column]} IS NOT ?", nil)
28
+ end
29
+
30
+ def delete_all!(conditions = nil)
31
+ self.unscoped.delete_all!(conditions)
32
+ end
33
+
34
+ def delete_all(conditions = nil)
35
+ update_all ["#{configuration[:column]} = ?", #{type}], conditions
36
+ end
37
+ end
38
+
39
+ def destroy!
40
+ before_destroy() if respond_to?(:before_destroy)
41
+
42
+ #{self.name}.delete_all!(:id => self)
43
+
44
+ after_destroy() if respond_to?(:after_destroy)
45
+ end
46
+
47
+ def destroy
48
+ run_callbacks :destroy do
49
+ if self.#{configuration[:column]} == nil
50
+ #{self.name}.delete_all(:id => self.id)
51
+ else
52
+ #{self.name}.delete_all!(:id => self.id)
53
+ end
54
+ end
55
+ end
56
+
57
+ def recover
58
+ self.update_attribute(:#{configuration[:column]}, nil)
59
+ end
60
+
61
+ ActiveRecord::Relation.class_eval do
62
+ alias_method :delete_all!, :delete_all
63
+ alias_method :destroy!, :destroy
64
+ end
65
+ EOV
66
+ end
67
+ end
68
+
69
+ # Extend ActiveRecord's functionality
70
+ ActiveRecord::Base.send :extend, ActsAsParanoid
71
+ ActiveRecord::Base.send :extend, ParanoidValidations::ClassMethods
@@ -0,0 +1,38 @@
1
+ require 'active_support/core_ext/array/wrap'
2
+
3
+ module ParanoidValidations
4
+ class UniquenessWithoutDeletedValidator < ActiveRecord::Validations::UniquenessValidator
5
+ def validate_each(record, attribute, value)
6
+ finder_class = find_finder_class_for(record)
7
+
8
+ if value && record.class.serialized_attributes.key?(attribute.to_s)
9
+ value = YAML.dump value
10
+ end
11
+
12
+ sql, params = mount_sql_and_params(finder_class, record.class.quoted_table_name, attribute, value)
13
+
14
+ # This is the only changed line from the base class version - it does finder_class.unscoped
15
+ relation = finder_class.where(sql, *params)
16
+
17
+ Array.wrap(options[:scope]).each do |scope_item|
18
+ scope_value = record.send(scope_item)
19
+ relation = relation.where(scope_item => scope_value)
20
+ end
21
+
22
+ if record.persisted?
23
+ # TODO : This should be in Arel
24
+ relation = relation.where("#{record.class.quoted_table_name}.#{record.class.primary_key} <> ?", record.send(:id))
25
+ end
26
+
27
+ if relation.exists?
28
+ record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
29
+ end
30
+ end
31
+ end
32
+
33
+ module ClassMethods
34
+ def validates_uniqueness_of_without_deleted(*attr_names)
35
+ validates_with UniquenessWithoutDeletedValidator, _merge_attributes(attr_names)
36
+ end
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gravelpup-rails3_acts_as_paranoid
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 5
9
+ version: 0.0.5
10
+ platform: ruby
11
+ authors:
12
+ - "Gon\xC3\xA7alo Silva"
13
+ - Jonathan Vaught
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-08 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: activerecord
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 3
31
+ - 0
32
+ version: "3.0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: Active Record (>=3.0) plugin which allows you to hide and restore records without actually deleting them. Check its GitHub page for more in-depth information.
36
+ email:
37
+ - jonathan.vaught@gmail.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - lib/rails3_acts_as_paranoid.rb
46
+ - lib/validations/uniqueness_without_deleted.rb
47
+ - LICENSE
48
+ - README.markdown
49
+ has_rdoc: true
50
+ homepage: http://github.com/gravelpup/rails3_acts_as_paranoid
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options: []
55
+
56
+ require_paths:
57
+ - lib
58
+ - lib/validations
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 1
74
+ - 3
75
+ - 7
76
+ version: 1.3.7
77
+ requirements: []
78
+
79
+ rubyforge_project: gravelpup-rails3_acts_as_paranoid
80
+ rubygems_version: 1.3.7
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Active Record (>=3.0) plugin which allows you to hide and restore records without actually deleting them.
84
+ test_files: []
85
+