deleted_at 0.4.0rc1 → 0.5.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/{spec/support/rails/public/favicon.ico → CHANGELOG.md} +0 -0
  3. data/{LICENSE.txt → LICENSE} +0 -0
  4. data/README.md +29 -15
  5. data/lib/deleted_at.rb +29 -29
  6. data/lib/deleted_at/active_record.rb +37 -0
  7. data/lib/deleted_at/core.rb +51 -0
  8. data/lib/deleted_at/{views.rb → legacy.rb} +23 -14
  9. data/lib/deleted_at/railtie.rb +5 -4
  10. data/lib/deleted_at/relation.rb +72 -0
  11. data/lib/deleted_at/table_definition.rb +10 -0
  12. data/lib/deleted_at/version.rb +1 -1
  13. metadata +30 -67
  14. data/.gitignore +0 -78
  15. data/.rspec +0 -2
  16. data/.travis.yml +0 -43
  17. data/CODE_OF_CONDUCT.md +0 -74
  18. data/Gemfile +0 -19
  19. data/Rakefile +0 -6
  20. data/deleted_at.gemspec +0 -42
  21. data/gemfiles/activerecord-4.0.Gemfile +0 -3
  22. data/gemfiles/activerecord-4.1.Gemfile +0 -3
  23. data/gemfiles/activerecord-4.2.Gemfile +0 -3
  24. data/gemfiles/activerecord-5.0.Gemfile +0 -3
  25. data/gemfiles/activerecord-5.1.Gemfile +0 -3
  26. data/lib/deleted_at/active_record/base.rb +0 -102
  27. data/lib/deleted_at/active_record/connection_adapters/abstract/schema_definition.rb +0 -17
  28. data/lib/deleted_at/active_record/relation.rb +0 -43
  29. data/spec/deleted_at/active_record/base_spec.rb +0 -21
  30. data/spec/deleted_at/active_record/relation_spec.rb +0 -166
  31. data/spec/deleted_at/views_spec.rb +0 -76
  32. data/spec/spec_helper.rb +0 -28
  33. data/spec/support/rails/app/models/animals/dog.rb +0 -5
  34. data/spec/support/rails/app/models/comment.rb +0 -6
  35. data/spec/support/rails/app/models/post.rb +0 -7
  36. data/spec/support/rails/app/models/user.rb +0 -7
  37. data/spec/support/rails/config/database.yml +0 -4
  38. data/spec/support/rails/config/routes.rb +0 -3
  39. data/spec/support/rails/db/schema.rb +0 -27
  40. data/spec/support/rails/log/.gitignore +0 -1
@@ -1,3 +0,0 @@
1
- eval_gemfile File.join(File.dirname(__FILE__), "../Gemfile")
2
-
3
- gem 'activerecord', '~> 4.0.0'
@@ -1,3 +0,0 @@
1
- eval_gemfile File.join(File.dirname(__FILE__), "../Gemfile")
2
-
3
- gem 'activerecord', '~> 4.1.0'
@@ -1,3 +0,0 @@
1
- eval_gemfile File.join(File.dirname(__FILE__), "../Gemfile")
2
-
3
- gem 'activerecord', '~> 4.2.0'
@@ -1,3 +0,0 @@
1
- eval_gemfile File.join(File.dirname(__FILE__), "../Gemfile")
2
-
3
- gem 'activerecord', '~> 5.0.0'
@@ -1,3 +0,0 @@
1
- eval_gemfile File.join(File.dirname(__FILE__), "../Gemfile")
2
-
3
- gem 'activerecord', '~> 5.1.0'
@@ -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