undeletable 0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +14 -5
- data/Rakefile +12 -8
- data/lib/undeletable.rb +102 -26
- data/lib/undeletable/version.rb +1 -1
- metadata +20 -21
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MjI3YzE0ZTIyZjIxODVkYTVlOGY2NDlmNTMwMjY5NmE4ZmRhYWE1Yw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZmUxOTc4OTNjZDMzZjRjZDRkNTMxNjAwZDRjMzk1YTY2ODkzNzJhNA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NDhjMzQwM2Q4ZDUyYjhiYzllMGU4ZTRiYTc4MWQzZjI5MTk3Nzc5OWNkYjMz
|
10
|
+
MWE4OGY0ZmZmMGVlMmM2YzdkMmQwYjA0Mjg5MzdhZDVmNjkwM2Y1ZDMxODU1
|
11
|
+
MDEzODUzM2EzY2U1YjZmZDM0MDg1NzY3ODUzNDk5YzNiZDhlMmY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ODZmYjIxNjA1OGI0M2JlZTI4ZWU3ZDU3NGQzYWE2M2YwMjNkZjkzMjYxMmJi
|
14
|
+
ZTlhN2UxM2JlNTJhMDdmMzkxZGQ3ODdmZjA3Yzc1NDYyZjYyZGU0MzQ4ZDFk
|
15
|
+
ZTU5MTdlZjhlM2FhNDY1MzVjNTJjNzBjMDUxMjNjZmRmZjM1NmQ=
|
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
[![Build Status](https://secure.travis-ci.org/FineLinePrototyping/undeletable.png?branch=master)][travis] [![Gem Version](https://badge.fury.io/rb/undeletable.png)][badgefury]
|
2
|
+
|
1
3
|
# Undeletable
|
2
4
|
|
3
|
-
|
5
|
+
`undeletable` on the model class disables the ability to `delete`/`destroy` on instance, model class, and via relation, using the default ActiveRecord version of those, and supports destroy callbacks if raise not enabled. `undeletable!` on the model class will raise an error when those are attempted. `destroy!` in Rails 4 is supported.
|
4
6
|
|
5
|
-
|
7
|
+
Tested with ActiveRecord 3.1.x, 3.2.x, and 4.0.x via travis and appraisal.
|
6
8
|
|
7
|
-
|
9
|
+
Code originally based on [Paranoia][paranoia] (by Ryan Bigg and others), but extremely modified to the point it really shares little in common now.
|
8
10
|
|
9
11
|
## Installation & Usage
|
10
12
|
|
@@ -28,7 +30,7 @@ Updating is as simple as `bundle update undeletable`.
|
|
28
30
|
|
29
31
|
```ruby
|
30
32
|
Undeletable.configure do
|
31
|
-
# if true
|
33
|
+
# if true, debug log failed attempts to delete/destroy when not raising error
|
32
34
|
self.debug = false
|
33
35
|
end
|
34
36
|
|
@@ -57,8 +59,15 @@ class Client < ActiveRecord::Base
|
|
57
59
|
end
|
58
60
|
```
|
59
61
|
|
62
|
+
## Upgrading
|
63
|
+
|
64
|
+
* v0.0.1 -> v1.0.x: `delete!` and `destroy!` no longer supported for now. `destroy!` has a Rails 4 naming conflict with same named method, and attempting to provide support for ActiveRecord::Relation made it too complicated for now (problems with infinite recursion requiring more state to setup and check, etc.). If you need to delete or destroy an undeletable model, the workaround is to comment the undeletable method on the class.
|
65
|
+
|
60
66
|
## License
|
61
67
|
|
62
|
-
This gem is released under the MIT license.
|
68
|
+
This gem is released under the [MIT license][lic].
|
63
69
|
|
70
|
+
[lic]: http://github.com/FineLinePrototyping/undeletable/blob/master/LICENSE
|
64
71
|
[paranoia]: https://github.com/radar/paranoia
|
72
|
+
[travis]: http://travis-ci.org/FineLinePrototyping/undeletable
|
73
|
+
[badgefury]: http://badge.fury.io/rb/undeletable
|
data/Rakefile
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
require 'appraisal'
|
3
4
|
|
4
|
-
task :
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
task :default do |t|
|
6
|
+
if ENV['BUNDLE_GEMFILE'] =~ /gemfiles/
|
7
|
+
load 'test/undeletable_test.rb'
|
8
|
+
else
|
9
|
+
exec 'bundle install && bundle exec rake appraise'
|
10
|
+
end
|
9
11
|
end
|
10
12
|
|
11
|
-
task :
|
13
|
+
task :appraise => ['appraisal:install'] do |t|
|
14
|
+
exec 'bundle install && bundle exec rake appraisal'
|
15
|
+
end
|
data/lib/undeletable.rb
CHANGED
@@ -3,55 +3,131 @@ require 'undeletable/version'
|
|
3
3
|
module Undeletable
|
4
4
|
class << self
|
5
5
|
attr_accessor :debug
|
6
|
-
def configure(&blk)
|
6
|
+
def configure(&blk)
|
7
|
+
class_eval(&blk)
|
8
|
+
end
|
7
9
|
end
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def undeletable?
|
15
|
+
true
|
16
|
+
end
|
12
17
|
|
13
|
-
|
14
|
-
|
18
|
+
def raise_on_delete?
|
19
|
+
self.raise_on_delete
|
20
|
+
end
|
21
|
+
|
22
|
+
def delete(id_or_array)
|
23
|
+
raise ActiveRecord::ReadOnlyRecord.new("#{self} is undeletable") if raise_on_delete?
|
24
|
+
logger.debug("will not #{self}.delete #{id_or_array.inspect}", e) if Undeletable.debug
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete_all(conditions = nil)
|
28
|
+
raise ActiveRecord::ReadOnlyRecord.new("#{self} is undeletable") if raise_on_delete?
|
29
|
+
logger.debug("will not #{self}.delete_all", e) if Undeletable.debug
|
30
|
+
end
|
15
31
|
end
|
16
32
|
|
17
33
|
def destroy
|
18
|
-
raise ActiveRecord::ReadOnlyRecord.new("#{self} is undeletable") if
|
34
|
+
raise ActiveRecord::ReadOnlyRecord.new("#{self} is undeletable") if raise_on_delete?
|
19
35
|
logger.debug("will not delete #{self}", e) if Undeletable.debug
|
20
36
|
run_callbacks(:destroy) { delete }
|
21
37
|
end
|
22
|
-
|
38
|
+
|
23
39
|
def delete
|
24
|
-
raise ActiveRecord::ReadOnlyRecord.new("#{self} is undeletable") if
|
40
|
+
raise ActiveRecord::ReadOnlyRecord.new("#{self} is undeletable") if raise_on_delete?
|
25
41
|
logger.debug("will not delete #{self}", e) if Undeletable.debug
|
26
42
|
end
|
27
43
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
44
|
+
end
|
45
|
+
|
46
|
+
module UndeletableRails4Extensions
|
47
|
+
extend ActiveSupport::Concern
|
48
|
+
|
49
|
+
def destroy!
|
50
|
+
raise ActiveRecord::RecordNotDestroyed.new("#{self} is undeletable")
|
51
|
+
end
|
32
52
|
end
|
33
53
|
|
34
54
|
Undeletable.configure do
|
35
55
|
self.debug = false
|
36
56
|
end
|
37
57
|
|
58
|
+
class ActiveRecord::Relation
|
59
|
+
# don't use generic naming to try to avoid conflicts, since this isn't model class specific
|
60
|
+
alias_method :undeletable_orig_relation_delete_all, :delete_all
|
61
|
+
def delete_all(*args, &block)
|
62
|
+
if klass.respond_to?(:undeletable?) && klass.undeletable?
|
63
|
+
raise ActiveRecord::ReadOnlyRecord.new("#{self} is undeletable") if klass.raise_on_delete?
|
64
|
+
logger.debug("will not #{self}.delete_all", e) if Undeletable.debug
|
65
|
+
else
|
66
|
+
undeletable_orig_relation_delete_all(*args, &block)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# don't use generic naming to try to avoid conflicts, since this isn't model class specific
|
71
|
+
alias_method :undeletable_orig_relation_destroy_all, :destroy_all
|
72
|
+
def destroy_all(*args, &block)
|
73
|
+
if klass.respond_to?(:undeletable?) && klass.undeletable?
|
74
|
+
raise ActiveRecord::ReadOnlyRecord.new("#{self} is undeletable") if klass.raise_on_delete?
|
75
|
+
logger.debug("will not #{self}.destroy_all", e) if Undeletable.debug
|
76
|
+
if conditions
|
77
|
+
where(*args, &block).to_a.each {|object| object.run_callbacks(:destroy) { delete } }.tap { reset }
|
78
|
+
else
|
79
|
+
to_a.each {|object| object.run_callbacks(:destroy) { delete } }.tap { reset }
|
80
|
+
end
|
81
|
+
else
|
82
|
+
undeletable_orig_relation_destroy_all(*args, &block)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
38
87
|
class ActiveRecord::Base
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
88
|
+
|
89
|
+
def self.undeletable
|
90
|
+
undeletable_init(false)
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.undeletable!
|
94
|
+
undeletable_init(true)
|
45
95
|
end
|
46
96
|
|
47
|
-
def self.undeletable
|
97
|
+
def self.undeletable?
|
98
|
+
false
|
99
|
+
end
|
100
|
+
|
101
|
+
def undeletable?
|
102
|
+
self.class.undeletable?
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.raise_on_delete?
|
106
|
+
false
|
107
|
+
end
|
108
|
+
|
109
|
+
def raise_on_delete?
|
110
|
+
self.class.raise_on_delete?
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def self.undeletable_init(raise_on_delete_val)
|
116
|
+
class_attribute :undeletable_enabled, instance_writer: true
|
117
|
+
self.undeletable_enabled = true
|
48
118
|
class_attribute :raise_on_delete, instance_writer: true
|
49
|
-
self.raise_on_delete =
|
50
|
-
|
51
|
-
|
119
|
+
self.raise_on_delete = raise_on_delete_val
|
120
|
+
class << self
|
121
|
+
alias_method :undeletable_orig_class_delete, :delete
|
122
|
+
alias_method :undeletable_orig_class_delete_all, :delete_all
|
123
|
+
end
|
124
|
+
alias_method :undeletable_orig_delete, :delete
|
125
|
+
alias_method :undeletable_orig_destroy, :destroy
|
52
126
|
include Undeletable
|
127
|
+
if defined?(ActiveRecord::VERSION::MAJOR) && ActiveRecord::VERSION::MAJOR > 3
|
128
|
+
alias_method :undeletable_orig_destroy!, :destroy!
|
129
|
+
include UndeletableRails4Extensions
|
130
|
+
end
|
53
131
|
end
|
54
|
-
|
55
|
-
def self.undeletable? ; false ; end
|
56
|
-
def undeletable? ; self.class.undeletable? ; end
|
57
132
|
end
|
133
|
+
|
data/lib/undeletable/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: undeletable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gary S. Weaver
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ! '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.
|
19
|
+
version: '3.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ! '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.
|
26
|
+
version: '3.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 3.
|
34
|
-
type: :
|
33
|
+
version: '3.1'
|
34
|
+
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ! '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 3.
|
40
|
+
version: '3.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: appraisal
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ! '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: sqlite3
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,22 +67,21 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - '
|
73
|
+
- - ! '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - '
|
80
|
+
- - ! '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0
|
83
|
-
description: Ignores or raises error on destroy/delete of an ActiveRecord model
|
84
|
-
|
85
|
-
modified fork of the Paranoia gem (by Ryan Bigg and others).
|
82
|
+
version: '0'
|
83
|
+
description: Ignores or raises error on destroy/delete of an ActiveRecord model, but
|
84
|
+
is not marked as read-only and can be created/updated.
|
86
85
|
email:
|
87
86
|
- garysweaver@gmail.com
|
88
87
|
executables: []
|
@@ -93,7 +92,7 @@ files:
|
|
93
92
|
- lib/undeletable.rb
|
94
93
|
- Rakefile
|
95
94
|
- README.md
|
96
|
-
homepage: https://github.com/
|
95
|
+
homepage: https://github.com/FineLinePrototyping/undeletable
|
97
96
|
licenses:
|
98
97
|
- MIT
|
99
98
|
metadata: {}
|
@@ -113,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
112
|
version: 1.3.6
|
114
113
|
requirements: []
|
115
114
|
rubyforge_project:
|
116
|
-
rubygems_version: 2.0.
|
115
|
+
rubygems_version: 2.0.6
|
117
116
|
signing_key:
|
118
117
|
specification_version: 4
|
119
118
|
summary: Stop destroy/delete on certain ActiveRecord models without disallowing other
|