deleted_at 0.2.6 → 0.3.0
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +16 -2
- data/README.md +5 -1
- data/deleted_at.gemspec +9 -6
- data/lib/deleted_at.rb +11 -1
- data/lib/deleted_at/active_record/base.rb +9 -24
- data/lib/deleted_at/railtie.rb +0 -2
- data/lib/deleted_at/version.rb +1 -1
- data/lib/deleted_at/views.rb +22 -12
- metadata +44 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a972a99558a55757fd3a8246f87b5ac0bc94308
|
4
|
+
data.tar.gz: 82771e5aea1cb90ec9d97bc1c7855c17f34d755e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 929ab80f479d1a37400d45232c357474038e2ffb0d55599c761ecee6f327104695bd00ae47bd93ddb41c41104d99a5de5384069900a57b8c7e7b311b60047f22
|
7
|
+
data.tar.gz: f7f73d1d179a03e468cd458bf3404b7e1c2b1116ac9e12ed4183725035d00696d0739457bee0fb865072b5cc18c5a3e7439928e016892b697612def031a31598
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,5 +1,19 @@
|
|
1
|
-
sudo: false
|
2
1
|
language: ruby
|
2
|
+
sudo: false
|
3
3
|
rvm:
|
4
|
+
- 2.0
|
5
|
+
- 2.1
|
6
|
+
- 2.2
|
4
7
|
- 2.3.1
|
5
|
-
|
8
|
+
- 2.4.0
|
9
|
+
cache: bundler
|
10
|
+
script:
|
11
|
+
- bundle exec rspec
|
12
|
+
services:
|
13
|
+
- postgresql
|
14
|
+
addons:
|
15
|
+
postgresql: "9.1"
|
16
|
+
|
17
|
+
env:
|
18
|
+
- RSPEC_VERSION="<2.99"
|
19
|
+
- RSPEC_VERSION="~>3.0
|
data/README.md
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
-
# DeletedAt
|
1
|
+
# DeletedAt [](https://travis-ci.org/TwilightCoders/deleted_at) [](https://codeclimate.com/github/TwilightCoders/deleted_at) [](https://codeclimate.com/github/TwilightCoders/deleted_at/coverage)
|
2
2
|
|
3
3
|
Deleting data is never good. A common solution is to use `default_scope`, but conventional wisdom (and for good reason) deams this a bad practice. So how do we achieve the same effect with minimal intervention. What we're looking for is the cliche "clean" solution.
|
4
4
|
|
5
5
|
DeletedAt leverages the power of SQL views to achieve the same effect. It also takes advantage of Ruby's flexibility.
|
6
6
|
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
`DeletedAt` requires PostgreSQL 9.1+ and Ruby 2.0.0+ (as the `pg` gem requires Ruby 2.0.0).
|
10
|
+
|
7
11
|
## Installation
|
8
12
|
|
9
13
|
Add this line to your application's Gemfile:
|
data/deleted_at.gemspec
CHANGED
@@ -25,18 +25,21 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
26
26
|
f.match(%r{^(test|spec|features)/})
|
27
27
|
end
|
28
|
+
|
28
29
|
spec.bindir = "exe"
|
29
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
31
|
spec.require_paths = ["lib"]
|
31
|
-
spec.required_ruby_version = '>= 2.0'
|
32
32
|
|
33
|
-
|
34
|
-
spec.
|
35
|
-
|
36
|
-
spec.
|
33
|
+
rails_versions = ['>= 4.1', '< 5']
|
34
|
+
spec.required_ruby_version = '>= 2.0.0'
|
35
|
+
|
36
|
+
spec.add_runtime_dependency 'pg', '~> 0'
|
37
|
+
spec.add_runtime_dependency "activerecord", rails_versions
|
37
38
|
|
38
|
-
spec.add_development_dependency "bundler", "~> 1.
|
39
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
39
40
|
spec.add_development_dependency "rake", "~> 10.0"
|
40
41
|
spec.add_development_dependency "rspec", "~> 3.0"
|
41
42
|
spec.add_development_dependency "pry", "~> 0.10"
|
43
|
+
spec.add_development_dependency "simplecov", ['>= 0.9.0', '<1.0.0']
|
44
|
+
spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0"
|
42
45
|
end
|
data/lib/deleted_at.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require "deleted_at/version"
|
2
|
-
require 'deleted_at/railtie'
|
3
2
|
require 'deleted_at/views'
|
3
|
+
require 'deleted_at/active_record/base'
|
4
|
+
require 'deleted_at/active_record/relation'
|
5
|
+
|
6
|
+
require 'deleted_at/railtie' if defined?(Rails::Railtie)
|
4
7
|
|
5
8
|
module DeletedAt
|
6
9
|
|
@@ -12,11 +15,18 @@ module DeletedAt
|
|
12
15
|
def self.install(model)
|
13
16
|
DeletedAt::Views.install_present_view(model)
|
14
17
|
DeletedAt::Views.install_deleted_view(model)
|
18
|
+
|
19
|
+
# Now that the views have been installed, initialize the new class extensions
|
20
|
+
# e.g. User -> User::All and User::Deleted
|
21
|
+
model.with_deleted_at
|
15
22
|
end
|
16
23
|
|
17
24
|
def self.uninstall(model)
|
18
25
|
DeletedAt::Views.uninstall_deleted_view(model)
|
19
26
|
DeletedAt::Views.uninstall_present_view(model)
|
27
|
+
|
28
|
+
# We've removed the database views, now remove the class extensions
|
29
|
+
model.remove_class_views
|
20
30
|
end
|
21
31
|
|
22
32
|
private
|
@@ -1,5 +1,5 @@
|
|
1
|
+
require 'active_record'
|
1
2
|
require 'deleted_at/views'
|
2
|
-
require 'deleted_at/active_record/relation'
|
3
3
|
|
4
4
|
module DeletedAt
|
5
5
|
module ActiveRecord
|
@@ -16,30 +16,12 @@ module DeletedAt
|
|
16
16
|
false
|
17
17
|
end
|
18
18
|
end
|
19
|
-
alias_method_chain :create, :deleted_at
|
20
|
-
alias_method_chain :create!, :deleted_at
|
21
19
|
end
|
22
20
|
|
23
21
|
end
|
24
22
|
|
25
23
|
module ClassMethods
|
26
24
|
|
27
|
-
def create_with_deleted_at(attributes = nil, &block)
|
28
|
-
if archive_with_deleted_at?
|
29
|
-
const_get(:All).create_without_deleted_at(attributes, &block).becomes(self)
|
30
|
-
else
|
31
|
-
create_without_deleted_at(attributes, &block)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def create_with_deleted_at!(attributes = nil, &block)
|
36
|
-
if archive_with_deleted_at?
|
37
|
-
const_get(:All).create_without_deleted_at!(attributes, &block).becomes(self)
|
38
|
-
else
|
39
|
-
create_without_deleted_at!(attributes, &block)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
25
|
def with_deleted_at(options={})
|
44
26
|
|
45
27
|
return warn("No DB connection found; skipping deleted_at initialization") unless ::ActiveRecord::Base.connected?
|
@@ -75,16 +57,20 @@ module DeletedAt
|
|
75
57
|
|
76
58
|
setup_class_views
|
77
59
|
with_deleted_by
|
60
|
+
end
|
78
61
|
|
62
|
+
def remove_class_views
|
63
|
+
self.send(:remove_const, :All) if self.const_defined?(:All)
|
64
|
+
self.send(:remove_const, :Deleted) if self.const_defined?(:Deleted)
|
79
65
|
end
|
80
66
|
|
81
67
|
private
|
82
68
|
|
83
69
|
def parse_options(options)
|
84
|
-
self.deleted_at_column = (options.
|
85
|
-
self.deleted_by_column = (options.
|
86
|
-
self.deleted_by_class = (options.
|
87
|
-
self.deleted_by_primary_key = (options.
|
70
|
+
self.deleted_at_column = (options.try(:[], :deleted_at).try(:[], :column) || :deleted_at).to_s
|
71
|
+
self.deleted_by_column = (options.try(:[], :deleted_by).try(:[], :column) || :deleted_by).to_s
|
72
|
+
self.deleted_by_class = (options.try(:[], :deleted_by).try(:[], :class) || User)
|
73
|
+
self.deleted_by_primary_key = (options.try(:[], :deleted_by).try(:[], :primary_key) || deleted_by_class.try(:primary_key)).to_s
|
88
74
|
end
|
89
75
|
|
90
76
|
def deleted_by_class_is_delete_at(klass)
|
@@ -112,7 +98,6 @@ module DeletedAt
|
|
112
98
|
end
|
113
99
|
|
114
100
|
def setup_class_views
|
115
|
-
|
116
101
|
self.const_set(:All, Class.new(self) do |klass|
|
117
102
|
class_eval <<-AAA
|
118
103
|
self.table_name = '#{::DeletedAt::Views.all_table(klass)}'
|
data/lib/deleted_at/railtie.rb
CHANGED
data/lib/deleted_at/version.rb
CHANGED
data/lib/deleted_at/views.rb
CHANGED
@@ -7,41 +7,41 @@ module DeletedAt
|
|
7
7
|
present_table_name = present_view(model)
|
8
8
|
|
9
9
|
model.connection.execute("ALTER TABLE \"#{present_table_name}\" RENAME TO \"#{all_table_name}\"")
|
10
|
-
model.connection.execute <<-
|
10
|
+
model.connection.execute <<-SQL
|
11
11
|
CREATE OR REPLACE VIEW "#{present_table_name}"
|
12
12
|
AS SELECT * FROM "#{all_table_name}" WHERE #{model.deleted_at_column} IS NULL;
|
13
|
-
|
13
|
+
SQL
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.install_deleted_view(model)
|
17
17
|
return warn("You must install the all/present tables/views first!") unless all_table_exists?(model)
|
18
18
|
table_name = deleted_view(model)
|
19
|
-
model.connection.execute <<-
|
19
|
+
model.connection.execute <<-SQL
|
20
20
|
CREATE OR REPLACE VIEW "#{table_name}"
|
21
21
|
AS SELECT * FROM "#{all_table(model)}" WHERE #{model.deleted_at_column} IS NOT NULL;
|
22
|
-
|
22
|
+
SQL
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.all_table_exists?(model)
|
26
|
-
query = model.connection.execute <<-
|
26
|
+
query = model.connection.execute <<-SQL
|
27
27
|
SELECT EXISTS (
|
28
28
|
SELECT 1
|
29
29
|
FROM information_schema.tables
|
30
|
-
WHERE
|
30
|
+
WHERE table_name = '#{all_table(model)}'
|
31
31
|
);
|
32
|
-
|
33
|
-
query
|
32
|
+
SQL
|
33
|
+
get_truthy_value_from_psql(query)
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.deleted_view_exists?(model)
|
37
|
-
query = model.connection.execute <<-
|
37
|
+
query = model.connection.execute <<-SQL
|
38
38
|
SELECT EXISTS (
|
39
39
|
SELECT 1
|
40
40
|
FROM information_schema.tables
|
41
|
-
WHERE
|
41
|
+
WHERE table_name = '#{deleted_view(model)}'
|
42
42
|
);
|
43
|
-
|
44
|
-
query
|
43
|
+
SQL
|
44
|
+
get_truthy_value_from_psql(query)
|
45
45
|
end
|
46
46
|
|
47
47
|
def self.present_view(model)
|
@@ -68,5 +68,15 @@ module DeletedAt
|
|
68
68
|
def self.uninstall_deleted_view(model)
|
69
69
|
model.connection.execute("DROP VIEW IF EXISTS \"#{deleted_view(model)}\"")
|
70
70
|
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def self.get_truthy_value_from_psql(result)
|
75
|
+
# Some versions of PSQL return {"?column?"=>"t"}
|
76
|
+
# instead of {"first"=>"t"}, so we're saying screw it,
|
77
|
+
# just give me the first value of whatever is returned
|
78
|
+
result.try(:first).try(:values).try(:first) == 't'
|
79
|
+
end
|
80
|
+
|
71
81
|
end
|
72
82
|
end
|
metadata
CHANGED
@@ -1,51 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deleted_at
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dale Stevens
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: pg
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
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: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.1'
|
34
|
+
- - "<"
|
32
35
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
36
|
+
version: '5'
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
|
-
- - "
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '4.1'
|
44
|
+
- - "<"
|
39
45
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
46
|
+
version: '5'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
48
|
+
name: bundler
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
44
50
|
requirements:
|
45
51
|
- - "~>"
|
46
52
|
- !ruby/object:Gem::Version
|
47
53
|
version: '1.3'
|
48
|
-
type: :
|
54
|
+
type: :development
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
51
57
|
requirements:
|
@@ -53,81 +59,81 @@ dependencies:
|
|
53
59
|
- !ruby/object:Gem::Version
|
54
60
|
version: '1.3'
|
55
61
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
62
|
+
name: rake
|
57
63
|
requirement: !ruby/object:Gem::Requirement
|
58
64
|
requirements:
|
59
65
|
- - "~>"
|
60
66
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
62
|
-
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '1.1'
|
65
|
-
type: :runtime
|
67
|
+
version: '10.0'
|
68
|
+
type: :development
|
66
69
|
prerelease: false
|
67
70
|
version_requirements: !ruby/object:Gem::Requirement
|
68
71
|
requirements:
|
69
72
|
- - "~>"
|
70
73
|
- !ruby/object:Gem::Version
|
71
|
-
version: '
|
72
|
-
- - ">="
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '1.1'
|
74
|
+
version: '10.0'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
76
|
+
name: rspec
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
81
|
+
version: '3.0'
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '3.0'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
|
-
name:
|
90
|
+
name: pry
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
93
|
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version: '10
|
95
|
+
version: '0.10'
|
96
96
|
type: :development
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
100
|
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: '10
|
102
|
+
version: '0.10'
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
|
-
name:
|
104
|
+
name: simplecov
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
|
-
- - "
|
107
|
+
- - ">="
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
109
|
+
version: 0.9.0
|
110
|
+
- - "<"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 1.0.0
|
110
113
|
type: :development
|
111
114
|
prerelease: false
|
112
115
|
version_requirements: !ruby/object:Gem::Requirement
|
113
116
|
requirements:
|
114
|
-
- - "
|
117
|
+
- - ">="
|
115
118
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
119
|
+
version: 0.9.0
|
120
|
+
- - "<"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 1.0.0
|
117
123
|
- !ruby/object:Gem::Dependency
|
118
|
-
name:
|
124
|
+
name: codeclimate-test-reporter
|
119
125
|
requirement: !ruby/object:Gem::Requirement
|
120
126
|
requirements:
|
121
127
|
- - "~>"
|
122
128
|
- !ruby/object:Gem::Version
|
123
|
-
version: '0
|
129
|
+
version: '1.0'
|
124
130
|
type: :development
|
125
131
|
prerelease: false
|
126
132
|
version_requirements: !ruby/object:Gem::Requirement
|
127
133
|
requirements:
|
128
134
|
- - "~>"
|
129
135
|
- !ruby/object:Gem::Version
|
130
|
-
version: '0
|
136
|
+
version: '1.0'
|
131
137
|
description: Default scopes are bad. Don't delete your data. DeletedAt, I choose you!
|
132
138
|
email:
|
133
139
|
- dale@twilightcoders.net
|
@@ -165,7 +171,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
165
171
|
requirements:
|
166
172
|
- - ">="
|
167
173
|
- !ruby/object:Gem::Version
|
168
|
-
version:
|
174
|
+
version: 2.0.0
|
169
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
176
|
requirements:
|
171
177
|
- - ">="
|
@@ -173,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
179
|
version: '0'
|
174
180
|
requirements: []
|
175
181
|
rubyforge_project:
|
176
|
-
rubygems_version: 2.
|
182
|
+
rubygems_version: 2.6.11
|
177
183
|
signing_key:
|
178
184
|
specification_version: 4
|
179
185
|
summary: Soft delete your data, but keep it clean.
|