deleted_at 0.4.0rc1 → 0.5.0.pre.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.
- checksums.yaml +4 -4
- data/{spec/support/rails/public/favicon.ico → CHANGELOG.md} +0 -0
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +29 -15
- data/lib/deleted_at.rb +29 -29
- data/lib/deleted_at/active_record.rb +37 -0
- data/lib/deleted_at/core.rb +51 -0
- data/lib/deleted_at/{views.rb → legacy.rb} +23 -14
- data/lib/deleted_at/railtie.rb +5 -4
- data/lib/deleted_at/relation.rb +72 -0
- data/lib/deleted_at/table_definition.rb +10 -0
- data/lib/deleted_at/version.rb +1 -1
- metadata +30 -67
- data/.gitignore +0 -78
- data/.rspec +0 -2
- data/.travis.yml +0 -43
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -19
- data/Rakefile +0 -6
- data/deleted_at.gemspec +0 -42
- data/gemfiles/activerecord-4.0.Gemfile +0 -3
- data/gemfiles/activerecord-4.1.Gemfile +0 -3
- data/gemfiles/activerecord-4.2.Gemfile +0 -3
- data/gemfiles/activerecord-5.0.Gemfile +0 -3
- data/gemfiles/activerecord-5.1.Gemfile +0 -3
- data/lib/deleted_at/active_record/base.rb +0 -102
- data/lib/deleted_at/active_record/connection_adapters/abstract/schema_definition.rb +0 -17
- data/lib/deleted_at/active_record/relation.rb +0 -43
- data/spec/deleted_at/active_record/base_spec.rb +0 -21
- data/spec/deleted_at/active_record/relation_spec.rb +0 -166
- data/spec/deleted_at/views_spec.rb +0 -76
- data/spec/spec_helper.rb +0 -28
- data/spec/support/rails/app/models/animals/dog.rb +0 -5
- data/spec/support/rails/app/models/comment.rb +0 -6
- data/spec/support/rails/app/models/post.rb +0 -7
- data/spec/support/rails/app/models/user.rb +0 -7
- data/spec/support/rails/config/database.yml +0 -4
- data/spec/support/rails/config/routes.rb +0 -3
- data/spec/support/rails/db/schema.rb +0 -27
- data/spec/support/rails/log/.gitignore +0 -1
@@ -1,102 +0,0 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
require 'deleted_at/views'
|
3
|
-
|
4
|
-
module DeletedAt
|
5
|
-
module ActiveRecord
|
6
|
-
module Base
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
included do
|
10
|
-
class_attribute :archive_with_deleted_at
|
11
|
-
class_attribute :deleted_at_column
|
12
|
-
|
13
|
-
self.archive_with_deleted_at = false
|
14
|
-
end
|
15
|
-
|
16
|
-
module ClassMethods
|
17
|
-
|
18
|
-
def with_deleted_at(options={})
|
19
|
-
|
20
|
-
DeletedAt::ActiveRecord::Base.parse_options(self, options)
|
21
|
-
|
22
|
-
return DeletedAt.logger.warn("You're trying to use `with_deleted_at` on #{name} but you have not installed the views, yet.") unless
|
23
|
-
has_deleted_at_views?
|
24
|
-
|
25
|
-
return DeletedAt.logger.warn("Missing `#{deleted_at_column}` in `#{name}` when trying to employ `deleted_at`") unless
|
26
|
-
has_deleted_at_column?
|
27
|
-
|
28
|
-
# We are confident at this point that the tables and views have been setup.
|
29
|
-
# We need to do a bit of wizardy by setting the table name to the actual table
|
30
|
-
# (at this point: model/all), such that the model has all the information
|
31
|
-
# regarding its structure and intended behavior. (e.g. setting primary key)
|
32
|
-
DeletedAt::Views.while_spoofing_table_name(self, ::DeletedAt::Views.all_table(self)) do
|
33
|
-
reset_primary_key
|
34
|
-
end
|
35
|
-
|
36
|
-
DeletedAt::ActiveRecord::Base.setup_class_views(self)
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
def has_deleted_at_column?
|
42
|
-
columns.map(&:name).include?(deleted_at_column)
|
43
|
-
end
|
44
|
-
|
45
|
-
def has_deleted_at_views?
|
46
|
-
::DeletedAt::Views.all_table_exists?(self) && ::DeletedAt::Views.deleted_view_exists?(self)
|
47
|
-
end
|
48
|
-
|
49
|
-
def deleted_at_attributes
|
50
|
-
attributes = {
|
51
|
-
deleted_at_column => Time.now.utc
|
52
|
-
}
|
53
|
-
|
54
|
-
|
55
|
-
attributes
|
56
|
-
end
|
57
|
-
|
58
|
-
end # End ClassMethods
|
59
|
-
|
60
|
-
def destroy
|
61
|
-
if self.archive_with_deleted_at?
|
62
|
-
with_transaction_returning_status do
|
63
|
-
run_callbacks :destroy do
|
64
|
-
update_columns(self.class.deleted_at_attributes)
|
65
|
-
self
|
66
|
-
end
|
67
|
-
end
|
68
|
-
else
|
69
|
-
super
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.remove_class_views(model)
|
74
|
-
model.archive_with_deleted_at = false
|
75
|
-
model.send(:remove_const, :All) if model.const_defined?(:All)
|
76
|
-
model.send(:remove_const, :Deleted) if model.const_defined?(:Deleted)
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.parse_options(model, options)
|
80
|
-
model.deleted_at_column = (options.try(:[], :deleted_at).try(:[], :column) || :deleted_at).to_s
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
def self.setup_class_views(model)
|
85
|
-
model.archive_with_deleted_at = true
|
86
|
-
model.const_set(:All, Class.new(model) do |klass|
|
87
|
-
class_eval <<-AAA
|
88
|
-
self.table_name = '#{::DeletedAt::Views.all_table(klass)}'
|
89
|
-
AAA
|
90
|
-
end)
|
91
|
-
|
92
|
-
model.const_set(:Deleted, Class.new(model) do |klass|
|
93
|
-
class_eval <<-AAA
|
94
|
-
self.table_name = '#{::DeletedAt::Views.deleted_view(klass)}'
|
95
|
-
AAA
|
96
|
-
end)
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
end
|
102
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module DeletedAt
|
2
|
-
module ActiveRecord
|
3
|
-
module ConnectionAdapters #:nodoc:
|
4
|
-
module TableDefinition
|
5
|
-
|
6
|
-
def timestamps(**options)
|
7
|
-
options[:null] = false if options[:null].nil?
|
8
|
-
|
9
|
-
column(:created_at, :datetime, options)
|
10
|
-
column(:updated_at, :datetime, options)
|
11
|
-
column(:deleted_at, :datetime, options.merge(null: true)) if options[:deleted_at]
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
|
2
|
-
module DeletedAt
|
3
|
-
module ActiveRecord
|
4
|
-
# = Active Record Relation
|
5
|
-
module Relation
|
6
|
-
|
7
|
-
# Deletes the records matching +conditions+ without instantiating the records
|
8
|
-
# first, and hence not calling the +destroy+ method nor invoking callbacks. This
|
9
|
-
# is a single SQL DELETE statement that goes straight to the database, much more
|
10
|
-
# efficient than +destroy_all+. Be careful with relations though, in particular
|
11
|
-
# <tt>:dependent</tt> rules defined on associations are not honored. Returns the
|
12
|
-
# number of rows affected.
|
13
|
-
#
|
14
|
-
# Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')")
|
15
|
-
# Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else'])
|
16
|
-
# Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all
|
17
|
-
#
|
18
|
-
# Both calls delete the affected posts all at once with a single DELETE statement.
|
19
|
-
# If you need to destroy dependent associations or call your <tt>before_*</tt> or
|
20
|
-
# +after_destroy+ callbacks, use the +destroy_all+ method instead.
|
21
|
-
#
|
22
|
-
# If an invalid method is supplied, +delete_all+ raises an ActiveRecord error:
|
23
|
-
#
|
24
|
-
# Post.limit(100).delete_all
|
25
|
-
# # => ActiveRecord::ActiveRecordError: delete_all doesn't support limit
|
26
|
-
def delete_all(*args)
|
27
|
-
conditions = args.pop
|
28
|
-
if archive_with_deleted_at?
|
29
|
-
if conditions
|
30
|
-
ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
|
31
|
-
Passing conditions to delete_all is not supported in DeletedAt
|
32
|
-
To achieve the same use where(conditions).delete_all.
|
33
|
-
MESSAGE
|
34
|
-
end
|
35
|
-
update_all(klass.deleted_at_attributes)
|
36
|
-
else
|
37
|
-
super() # Specifically drop args
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe DeletedAt::ActiveRecord::Base do
|
4
|
-
|
5
|
-
context "model missing deleted_at column" do
|
6
|
-
|
7
|
-
it "fails when trying to install" do
|
8
|
-
expect(DeletedAt.install(Comment)).to eq(false)
|
9
|
-
expect(DeletedAt.uninstall(Comment)).to eq(false)
|
10
|
-
end
|
11
|
-
|
12
|
-
it "warns when using with_deleted_at" do
|
13
|
-
expected_stderr = "Missing `deleted_at` in `Comment` when trying to employ `deleted_at`"
|
14
|
-
allow(Comment).to receive(:has_deleted_at_views?).and_return(true)
|
15
|
-
expect(DeletedAt.logger).to receive(:warn).with(expected_stderr)
|
16
|
-
Comment.with_deleted_at
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
@@ -1,166 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe DeletedAt::ActiveRecord::Relation do
|
4
|
-
|
5
|
-
context "models using deleted_at" do
|
6
|
-
|
7
|
-
it "#destroy should set deleted_at" do
|
8
|
-
DeletedAt.install(User)
|
9
|
-
User.create(name: 'bob')
|
10
|
-
User.create(name: 'john')
|
11
|
-
User.create(name: 'sally')
|
12
|
-
|
13
|
-
User.first.destroy
|
14
|
-
|
15
|
-
expect(User.count).to eq(2)
|
16
|
-
expect(User::All.count).to eq(3)
|
17
|
-
expect(User::Deleted.count).to eq(1)
|
18
|
-
DeletedAt.uninstall(User)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "#delete should set deleted_at" do
|
22
|
-
DeletedAt.install(User)
|
23
|
-
User.create(name: 'bob')
|
24
|
-
User.create(name: 'john')
|
25
|
-
User.create(name: 'sally')
|
26
|
-
|
27
|
-
User.first.delete
|
28
|
-
|
29
|
-
expect(User.count).to eq(2)
|
30
|
-
expect(User::All.count).to eq(3)
|
31
|
-
expect(User::Deleted.count).to eq(1)
|
32
|
-
DeletedAt.uninstall(User)
|
33
|
-
end
|
34
|
-
|
35
|
-
context '#destroy_all' do
|
36
|
-
it "should set deleted_at" do
|
37
|
-
DeletedAt.install(User)
|
38
|
-
User.create(name: 'bob')
|
39
|
-
User.create(name: 'john')
|
40
|
-
User.create(name: 'sally')
|
41
|
-
|
42
|
-
User.all.destroy_all
|
43
|
-
|
44
|
-
expect(User.count).to eq(0)
|
45
|
-
expect(User::All.count).to eq(3)
|
46
|
-
expect(User::Deleted.count).to eq(3)
|
47
|
-
DeletedAt.uninstall(User)
|
48
|
-
end
|
49
|
-
|
50
|
-
it "with conditions should set deleted_at" do
|
51
|
-
DeletedAt.install(User)
|
52
|
-
User.create(name: 'bob')
|
53
|
-
User.create(name: 'john')
|
54
|
-
User.create(name: 'sally')
|
55
|
-
|
56
|
-
User.where(name: 'bob').destroy_all
|
57
|
-
|
58
|
-
expect(User.count).to eq(2)
|
59
|
-
expect(User::All.count).to eq(3)
|
60
|
-
expect(User::Deleted.count).to eq(1)
|
61
|
-
DeletedAt.uninstall(User)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context '#delete_all' do
|
66
|
-
it "should set deleted_at" do
|
67
|
-
DeletedAt.install(Animals::Dog)
|
68
|
-
Animals::Dog.create(name: 'bob')
|
69
|
-
Animals::Dog.create(name: 'john')
|
70
|
-
Animals::Dog.create(name: 'sally')
|
71
|
-
|
72
|
-
# conditions should not matter
|
73
|
-
Animals::Dog.all.delete_all(name: 'bob')
|
74
|
-
|
75
|
-
expect(Animals::Dog.count).to eq(0)
|
76
|
-
expect(Animals::Dog::All.count).to eq(3)
|
77
|
-
expect(Animals::Dog::Deleted.count).to eq(3)
|
78
|
-
DeletedAt.uninstall(Animals::Dog)
|
79
|
-
end
|
80
|
-
|
81
|
-
it "with conditions should set deleted_at" do
|
82
|
-
DeletedAt.install(Animals::Dog)
|
83
|
-
Animals::Dog.create(name: 'bob')
|
84
|
-
Animals::Dog.create(name: 'john')
|
85
|
-
Animals::Dog.create(name: 'sally')
|
86
|
-
|
87
|
-
Animals::Dog.where(name: 'bob').delete_all
|
88
|
-
|
89
|
-
expect(Animals::Dog.count).to eq(2)
|
90
|
-
expect(Animals::Dog::All.count).to eq(3)
|
91
|
-
expect(Animals::Dog::Deleted.count).to eq(1)
|
92
|
-
DeletedAt.uninstall(Animals::Dog)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
context "models not using deleted_at" do
|
99
|
-
|
100
|
-
it "#destroy should actually delete the record" do
|
101
|
-
Comment.create(title: 'Agree')
|
102
|
-
Comment.create(title: 'Disagree')
|
103
|
-
Comment.create(title: 'Defer')
|
104
|
-
|
105
|
-
Comment.first.destroy
|
106
|
-
|
107
|
-
expect(Comment.count).to eq(2)
|
108
|
-
end
|
109
|
-
|
110
|
-
it "#delete should actually delete the record" do
|
111
|
-
Comment.create(title: 'Agree')
|
112
|
-
Comment.create(title: 'Disagree')
|
113
|
-
Comment.create(title: 'Defer')
|
114
|
-
|
115
|
-
Comment.first.delete
|
116
|
-
|
117
|
-
expect(Comment.count).to eq(2)
|
118
|
-
end
|
119
|
-
|
120
|
-
context '#destroy_all' do
|
121
|
-
it "should actually delete records" do
|
122
|
-
Comment.create(title: 'Agree')
|
123
|
-
Comment.create(title: 'Disagree')
|
124
|
-
Comment.create(title: 'Defer')
|
125
|
-
|
126
|
-
Comment.all.destroy_all
|
127
|
-
|
128
|
-
expect(Comment.count).to eq(0)
|
129
|
-
end
|
130
|
-
|
131
|
-
it "with conditions should actually delete records" do
|
132
|
-
Comment.create(title: 'Agree')
|
133
|
-
Comment.create(title: 'Disagree')
|
134
|
-
Comment.create(title: 'Defer')
|
135
|
-
|
136
|
-
Comment.where(title: 'Disagree').destroy_all
|
137
|
-
|
138
|
-
expect(Comment.count).to eq(2)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
context '#delete_all' do
|
143
|
-
it "should actually delete records" do
|
144
|
-
Comment.create(title: 'Agree')
|
145
|
-
Comment.create(title: 'Disagree')
|
146
|
-
Comment.create(title: 'Defer')
|
147
|
-
|
148
|
-
Comment.all.delete_all
|
149
|
-
|
150
|
-
expect(Comment.count).to eq(0)
|
151
|
-
end
|
152
|
-
|
153
|
-
it "with conditions should actually delete records" do
|
154
|
-
Comment.create(title: 'Agree')
|
155
|
-
Comment.create(title: 'Disagree')
|
156
|
-
Comment.create(title: 'Defer')
|
157
|
-
|
158
|
-
Comment.where(title: 'Agree').delete_all
|
159
|
-
|
160
|
-
expect(Comment.count).to eq(2)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
end
|
165
|
-
|
166
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe DeletedAt::Views do
|
4
|
-
{
|
5
|
-
User => "simple model",
|
6
|
-
Post => "model with customized table_name",
|
7
|
-
Animals::Dog => "namespaced model"
|
8
|
-
}.each do |model, description|
|
9
|
-
|
10
|
-
plural = model.name.pluralize
|
11
|
-
table_name = model.table_name
|
12
|
-
|
13
|
-
describe "#install for #{description}" do
|
14
|
-
after(:each) do
|
15
|
-
DeletedAt.uninstall(model)
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'should not raise error' do
|
19
|
-
expect{ DeletedAt.install(model) }.to_not raise_error()
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'should rename the models table' do
|
23
|
-
DeletedAt.install(model)
|
24
|
-
expect(ActiveRecord::Base.connection.table_exists?("#{table_name}/all")).to be_truthy
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should have a view for all non-deleted #{plural}" do
|
28
|
-
DeletedAt.install(model)
|
29
|
-
if Gem::Version.new(Rails.version) < Gem::Version.new("5.0")
|
30
|
-
expect(ActiveRecord::Base.connection.table_exists?(table_name)).to be_truthy
|
31
|
-
else
|
32
|
-
expect(ActiveRecord::Base.connection.view_exists?(table_name)).to be_truthy
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should have a view for all deleted #{plural}" do
|
37
|
-
DeletedAt.install(model)
|
38
|
-
if Gem::Version.new(Rails.version) < Gem::Version.new("5.0")
|
39
|
-
expect(ActiveRecord::Base.connection.table_exists?("#{table_name}/deleted")).to be_truthy
|
40
|
-
else
|
41
|
-
expect(ActiveRecord::Base.connection.view_exists?("#{table_name}/deleted")).to be_truthy
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'creates the DeletedAt class extensions' do
|
46
|
-
DeletedAt.install(model)
|
47
|
-
expect(model.const_defined?(:All)).to be_truthy
|
48
|
-
expect(model.const_defined?(:Deleted)).to be_truthy
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'sets the correct table name for modified class' do
|
52
|
-
DeletedAt.install(model)
|
53
|
-
expect(model.table_name).to eql(table_name)
|
54
|
-
expect(model::All.table_name).to eql("#{table_name}/all")
|
55
|
-
expect(model::Deleted.table_name).to eql("#{table_name}/deleted")
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe "#uninstall for #{description}" do
|
60
|
-
before(:each) do
|
61
|
-
DeletedAt.install(model)
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'should not raise error' do
|
65
|
-
expect{ DeletedAt.uninstall(model) }.to_not raise_error()
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'should remove model extensions' do
|
69
|
-
DeletedAt.uninstall(model)
|
70
|
-
expect(model.const_defined?(:All)).to be_falsy
|
71
|
-
expect(model.const_defined?(:Deleted)).to be_falsy
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|