soft_delete_rails 0.0.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 +7 -0
- data/.gitignore +23 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +107 -0
- data/Rakefile +10 -0
- data/lib/soft_delete_rails/has_soft_delete.rb +91 -0
- data/lib/soft_delete_rails/scopes.rb +11 -0
- data/lib/soft_delete_rails/version.rb +3 -0
- data/lib/soft_delete_rails.rb +6 -0
- data/soft_delete_rails.gemspec +24 -0
- data/soft_delete_test +0 -0
- data/test/configuration/database.yml +3 -0
- data/test/configuration/schema.rb +30 -0
- data/test/models/account.rb +4 -0
- data/test/models/address.rb +4 -0
- data/test/models/group.rb +5 -0
- data/test/models/phone_number.rb +3 -0
- data/test/models/user.rb +6 -0
- data/test/soft_delete_rails_test.rb +221 -0
- data/test/soft_delete_test +0 -0
- data/test/test_helper.rb +28 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c328fc357734d05ff5f8d6221db439a5e5c35eba
|
4
|
+
data.tar.gz: ad34b111cb04d338eab528086a7a732f73f4f53b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f6e92a7f9b4b50939a56e3c77e1904d335e871208eafc237ec66fc0d9ff3dbc70cc9d79e506d7e984683f422c4d1e651e426a4d528df3774841ae4a0273d4ff4
|
7
|
+
data.tar.gz: d51f40ea74aed36ffa06e4cdb1bdb66d3a5db9644bd9d4c901a0135e9aaf70fa92500c20bbc4fe9cfa9b9dfbf65f6324784173a96d5f58b799cf03132e77224e
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
.idea
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
soft_delete_rails
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.1.1
|
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in soft_delete_rails.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'activesupport', '4.1.0'
|
8
|
+
gem 'minitest'
|
9
|
+
gem 'minitest-reporters'
|
10
|
+
gem 'sqlite3'
|
11
|
+
gem 'database_cleaner'
|
12
|
+
gem 'shoulda'
|
13
|
+
gem 'turn'
|
14
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Andrew Medeiros
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# Soft Delete Rails
|
2
|
+
|
3
|
+
Soft deletion for rails. Includes default scoping and skipping validations. Features soft deletion of dependent records as well as reviving of dependent records.
|
4
|
+
Supports ActiveRecord >= 4.1.0
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'soft_delete_rails'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install soft_delete_rails
|
19
|
+
|
20
|
+
## Requierments
|
21
|
+
Datetime column deleted_at
|
22
|
+
|
23
|
+
class CreateUsers < ActiveRecord::Migration
|
24
|
+
def up
|
25
|
+
create_table :users, do |t|
|
26
|
+
t.datetime :deleted_at
|
27
|
+
t.timestamps
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
## Scopes
|
33
|
+
Default scope (optional)
|
34
|
+
|
35
|
+
where(deleted_at: nil)
|
36
|
+
Deleted scope (non-optional)
|
37
|
+
|
38
|
+
unscope(where: :deleted_at).where.not(deleted_at: nil)
|
39
|
+
|
40
|
+
## Options
|
41
|
+
Default usage includes the default scope and running model validations
|
42
|
+
|
43
|
+
class User < ActiveRecord::Base
|
44
|
+
has_soft_delete
|
45
|
+
end
|
46
|
+
|
47
|
+
Without default scope
|
48
|
+
|
49
|
+
class User < ActiveRecord::Base
|
50
|
+
has_soft_delete default_scope: false
|
51
|
+
end
|
52
|
+
|
53
|
+
Without validations. Will not run the model validations on soft delete or revive
|
54
|
+
|
55
|
+
class User < ActiveRecord::Base
|
56
|
+
has_soft_delete validate: false
|
57
|
+
end
|
58
|
+
|
59
|
+
Without default scope and validations
|
60
|
+
|
61
|
+
class User < ActiveRecord::Base
|
62
|
+
has_soft_delete default_scope: false, validate: false
|
63
|
+
end
|
64
|
+
|
65
|
+
## Dependent
|
66
|
+
Requires both models to have has_soft_delete and deleted_at column
|
67
|
+
|
68
|
+
class User < ActiveRecord::Base
|
69
|
+
belongs_to :group
|
70
|
+
has_soft_delete
|
71
|
+
end
|
72
|
+
|
73
|
+
# Will soft delete and revive the user records
|
74
|
+
class Group < ActiveRecord::Base
|
75
|
+
has_many :users, dependent: :destroy
|
76
|
+
has_soft_delete
|
77
|
+
end
|
78
|
+
|
79
|
+
## Destroy
|
80
|
+
|
81
|
+
group = Group.last
|
82
|
+
|
83
|
+
# Will soft delete the record and any dependent records with has_soft_delete
|
84
|
+
group.destroy
|
85
|
+
|
86
|
+
# Will hard delete the record from the database and any dependent records
|
87
|
+
group.destroy(:force)
|
88
|
+
|
89
|
+
|
90
|
+
## Revive
|
91
|
+
|
92
|
+
group = Group.deleted.last
|
93
|
+
|
94
|
+
# Will revive the record and any dependent records with has_soft_delete
|
95
|
+
group.revive
|
96
|
+
|
97
|
+
|
98
|
+
## Author
|
99
|
+
Andrew Medeiros, amedeiros0920@gmail.com, @_AndrewMedeiros
|
100
|
+
|
101
|
+
## Contributing
|
102
|
+
|
103
|
+
1. Fork it ( https://github.com/amedeiros/soft_delete_rails/fork )
|
104
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
105
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
106
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
107
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
module SoftDeleteRails
|
2
|
+
module Model
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def has_soft_delete(options = {})
|
9
|
+
# Lazy load the instance methods
|
10
|
+
send :include, InstanceMethods
|
11
|
+
|
12
|
+
class_attribute :delete_options
|
13
|
+
self.delete_options = options
|
14
|
+
|
15
|
+
# Set scopes
|
16
|
+
SoftDeleteRails::Scopes.default(self) unless options[:default_scope] == false
|
17
|
+
SoftDeleteRails::Scopes.deleted(self)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module InstanceMethods
|
22
|
+
def destroy(force=nil)
|
23
|
+
if force == :force
|
24
|
+
if super()
|
25
|
+
hard_destroy_dependent_records
|
26
|
+
end
|
27
|
+
else
|
28
|
+
run_callbacks(:destroy) do
|
29
|
+
soft_deleted? || new_record? ? save : update_deleted_at(Time.current)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def revive
|
35
|
+
if soft_deleted?
|
36
|
+
update_deleted_at(nil)
|
37
|
+
revive_dependent_records
|
38
|
+
return self.reload # return self reloaded
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def soft_deleted?
|
43
|
+
deleted_at.present?
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def update_deleted_at(value)
|
49
|
+
self.deleted_at = value
|
50
|
+
if self.class.delete_options[:validate] == false
|
51
|
+
save(validate: false)
|
52
|
+
else
|
53
|
+
save!
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def revive_dependent_records
|
58
|
+
reflections.each do |key, relation|
|
59
|
+
if relation.options[:dependent] == :destroy
|
60
|
+
records = Array.wrap(send(key).try(:deleted)) if key.to_s.singularize.camelize.constantize.column_names.include?('deleted_at')
|
61
|
+
records = Array.wrap(send(key)) if records.blank?
|
62
|
+
records.to_a.each do |record|
|
63
|
+
record.revive if record.respond_to?(:revive)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Perform a hard destroy on the dependent records
|
70
|
+
def hard_destroy_dependent_records
|
71
|
+
reflections.each do |key, relation|
|
72
|
+
if relation.options[:dependent] == :destroy
|
73
|
+
records = send(key).try(:unscope, where: :deleted_at) if key.to_s.singularize.camelize.constantize.column_names.include?('deleted_at')
|
74
|
+
records = Array.wrap(send(key)) if records.blank?
|
75
|
+
records.each do |record|
|
76
|
+
if record.respond_to?(:soft_deleted?)
|
77
|
+
record.destroy(:force)
|
78
|
+
else
|
79
|
+
record.destroy
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def reflections
|
87
|
+
self.class.reflections
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module SoftDeleteRails
|
2
|
+
class Scopes
|
3
|
+
def self.default(model)
|
4
|
+
model.class_eval { default_scope { where(deleted_at: nil) } }
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.deleted(model)
|
8
|
+
model.class_eval { scope :deleted, -> { unscope(where: :deleted_at).where.not(deleted_at: nil) } }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'soft_delete_rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'soft_delete_rails'
|
8
|
+
spec.version = SoftDeleteRails::VERSION
|
9
|
+
spec.authors = ['Andrew Medeiros']
|
10
|
+
spec.email = ['amedeiros0920@gmail.com']
|
11
|
+
spec.summary = %q{Soft delete records within rails}
|
12
|
+
spec.description = %q{Soft delete records within rails}
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_development_dependency 'activerecord', '4.1.0'
|
24
|
+
end
|
data/soft_delete_test
ADDED
Binary file
|
@@ -0,0 +1,30 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
create_table :groups, force: true do |t|
|
3
|
+
t.datetime :deleted_at
|
4
|
+
t.string :name
|
5
|
+
t.timestamps
|
6
|
+
end
|
7
|
+
|
8
|
+
create_table :accounts, force: true do |t|
|
9
|
+
t.datetime :deleted_at
|
10
|
+
t.string :name
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
create_table :users, force: true do |t|
|
15
|
+
t.datetime :deleted_at
|
16
|
+
t.belongs_to :group
|
17
|
+
t.timestamps
|
18
|
+
end
|
19
|
+
|
20
|
+
create_table :phone_numbers, force: true do |t|
|
21
|
+
t.belongs_to :user
|
22
|
+
t.timestamps
|
23
|
+
end
|
24
|
+
|
25
|
+
create_table :addresses, force: true do |t|
|
26
|
+
t.belongs_to :user
|
27
|
+
t.datetime :deleted_at
|
28
|
+
t.timestamps
|
29
|
+
end
|
30
|
+
end
|
data/test/models/user.rb
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
class SoftDeleteRailsTest < ActiveSupport::TestCase
|
4
|
+
context SoftDeleteRails do
|
5
|
+
setup do
|
6
|
+
DatabaseCleaner.strategy = :truncation
|
7
|
+
DatabaseCleaner.start
|
8
|
+
end
|
9
|
+
|
10
|
+
teardown do
|
11
|
+
DatabaseCleaner.clean
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'soft deletion' do
|
15
|
+
should 'should set the deleted_at' do
|
16
|
+
user = User.create
|
17
|
+
assert_difference 'User.count', -1 do
|
18
|
+
user.destroy
|
19
|
+
assert user.deleted_at.present?
|
20
|
+
assert user.soft_deleted?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'dependents' do
|
25
|
+
setup do
|
26
|
+
@group = Group.create(name: 'test')
|
27
|
+
@user = User.create(group: @group)
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'soft delete dependent records' do
|
31
|
+
assert_difference ['Group.count', 'User.count'], -1 do
|
32
|
+
assert @group.destroy
|
33
|
+
assert @group.soft_deleted?
|
34
|
+
assert @user.reload.soft_deleted?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
should 'not soft destroy other non related records' do
|
39
|
+
# The scoping should not delete these records
|
40
|
+
group1 = Group.create(name: 'testing')
|
41
|
+
user1 = User.create(group: group1)
|
42
|
+
|
43
|
+
assert_difference ['Group.count', 'User.count'], -1 do
|
44
|
+
assert @group.destroy
|
45
|
+
assert @group.soft_deleted?
|
46
|
+
assert @user.reload.soft_deleted?
|
47
|
+
refute group1.reload.soft_deleted?
|
48
|
+
refute user1.reload.soft_deleted?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
should 'hard delete a dependent record that does not have has_soft_delete' do
|
53
|
+
PhoneNumber.create(user: @user)
|
54
|
+
assert_difference ['User.count', 'PhoneNumber.count'], -1 do
|
55
|
+
assert @user.destroy
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'has_one' do
|
60
|
+
should 'soft delete a has_one relation' do
|
61
|
+
# A User has one address
|
62
|
+
address = Address.create(user: @user)
|
63
|
+
assert_difference ['User.count', 'Address.count'], -1 do
|
64
|
+
assert @user.destroy
|
65
|
+
assert address.reload.soft_deleted?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'revive' do
|
73
|
+
should 'revive a record' do
|
74
|
+
user = User.create
|
75
|
+
# Soft destroy the record
|
76
|
+
assert user.destroy
|
77
|
+
assert user.soft_deleted?
|
78
|
+
|
79
|
+
# Revive the record
|
80
|
+
assert user.revive
|
81
|
+
refute user.soft_deleted?
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'dependents' do
|
85
|
+
setup do
|
86
|
+
@group = Group.create(name: 'test', deleted_at: Time.current)
|
87
|
+
@user = User.create(group: @group, deleted_at: Time.current)
|
88
|
+
end
|
89
|
+
|
90
|
+
should 'revive dependent records' do
|
91
|
+
# Revive the group and its relations
|
92
|
+
assert @group.revive
|
93
|
+
refute @group.soft_deleted?
|
94
|
+
refute @group.reload.soft_deleted?
|
95
|
+
end
|
96
|
+
|
97
|
+
should 'not revive non related records' do
|
98
|
+
group = Group.create(name: 'testing', deleted_at: Time.current)
|
99
|
+
user = User.create(group: group, deleted_at: Time.current)
|
100
|
+
# Revive the group and its relations
|
101
|
+
assert @group.revive
|
102
|
+
refute @group.soft_deleted?
|
103
|
+
refute @group.reload.soft_deleted?
|
104
|
+
|
105
|
+
# Should not be revived
|
106
|
+
assert group.soft_deleted?
|
107
|
+
assert user.soft_deleted?
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'has_one' do
|
111
|
+
should 'revive a has_one relation' do
|
112
|
+
address = Address.create(user: @user)
|
113
|
+
assert @user.destroy
|
114
|
+
assert address.reload.soft_deleted?
|
115
|
+
|
116
|
+
# Revive the user
|
117
|
+
assert @user.revive
|
118
|
+
# Should of revived the has one relation
|
119
|
+
refute address.reload.soft_deleted?
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'hard deletion' do
|
126
|
+
should 'hard delete a record' do
|
127
|
+
user = User.create
|
128
|
+
assert_difference 'User.unscoped.count', -1 do
|
129
|
+
assert user.destroy(:force)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'dependents' do
|
134
|
+
setup do
|
135
|
+
@group = Group.create(name: 'test')
|
136
|
+
@user = User.create(group: @group)
|
137
|
+
end
|
138
|
+
|
139
|
+
should 'hard delete dependent records' do
|
140
|
+
assert_difference ['Group.unscoped.count', 'User.unscoped.count'], -1 do
|
141
|
+
assert @group.destroy(:force)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
should 'hard delete dependent records that have been soft deleted' do
|
146
|
+
@user.destroy
|
147
|
+
assert @user.soft_deleted?
|
148
|
+
assert_difference ['Group.unscoped.count', 'User.unscoped.count'], -1 do
|
149
|
+
assert @group.destroy(:force)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
should 'not hard delete other non related records' do
|
154
|
+
# The scoping should not delete these records
|
155
|
+
group = Group.create(name: 'testing')
|
156
|
+
user = User.create(group: group)
|
157
|
+
|
158
|
+
assert_difference ['Group.count', 'User.count'], -1 do
|
159
|
+
assert @group.destroy(:force)
|
160
|
+
refute group.reload.soft_deleted?
|
161
|
+
refute user.reload.soft_deleted?
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
should 'hard delete a dependent record that does not have has_soft_delete' do
|
166
|
+
PhoneNumber.create(user: @user)
|
167
|
+
assert_difference ['User.count', 'PhoneNumber.count'], -1 do
|
168
|
+
assert @user.destroy
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'has_one' do
|
173
|
+
should 'hard delete a has_one relation' do
|
174
|
+
# A User has one address
|
175
|
+
Address.create(user: @user)
|
176
|
+
assert_difference ['User.unscoped.count', 'Address.unscoped.count'], -1 do
|
177
|
+
assert @user.destroy(:force)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'scopes' do
|
185
|
+
context 'default' do
|
186
|
+
should 'have the default scope' do
|
187
|
+
assert_equal User.all.to_sql, User.where(deleted_at: nil).to_sql
|
188
|
+
end
|
189
|
+
|
190
|
+
should 'not have the default scope' do
|
191
|
+
assert_not_equal Account.all.to_sql, Account.where(deleted_at: nil).to_sql
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'deleted' do
|
196
|
+
should 'have the deleted scope' do
|
197
|
+
assert_equal User.deleted.to_sql, User.unscoped.where.not(deleted_at: nil).to_sql
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'validations' do
|
203
|
+
should 'raise ActiveRecord::RecordInvalid for an invalid record' do
|
204
|
+
group = Group.create(name: 'test')
|
205
|
+
error = assert_raises ActiveRecord::RecordInvalid do
|
206
|
+
group.name = nil
|
207
|
+
group.destroy
|
208
|
+
end
|
209
|
+
assert_equal 'Validation failed: Name can\'t be blank', error.message, error.message.inspect
|
210
|
+
end
|
211
|
+
|
212
|
+
should 'not raise ActiveRecord::RecordInvalid for an invalid record' do
|
213
|
+
account = Account.create(name: 'test')
|
214
|
+
assert_nothing_raised do
|
215
|
+
account.name = nil
|
216
|
+
assert account.destroy
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
Binary file
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'minitest/reporters'
|
3
|
+
require 'pathname'
|
4
|
+
require 'active_record'
|
5
|
+
require 'active_support'
|
6
|
+
require 'database_cleaner'
|
7
|
+
require 'soft_delete_rails'
|
8
|
+
require 'shoulda'
|
9
|
+
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
10
|
+
|
11
|
+
module Rails
|
12
|
+
def self.env
|
13
|
+
'test'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
configuration = Pathname.new File.expand_path('configuration', File.dirname(__FILE__))
|
18
|
+
models = Pathname.new File.expand_path('models', File.dirname(__FILE__))
|
19
|
+
Dir.glob(models.join('*.rb')).each do |file|
|
20
|
+
autoload File.basename(file).chomp('.rb').camelcase.intern, file
|
21
|
+
end.each do |file|
|
22
|
+
require file
|
23
|
+
end
|
24
|
+
|
25
|
+
# Setup ActiveRecord
|
26
|
+
ActiveRecord::Base.configurations = YAML.load_file configuration.join('database.yml')
|
27
|
+
ActiveRecord::Base.establish_connection
|
28
|
+
load configuration.join('schema.rb')
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: soft_delete_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Medeiros
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activerecord
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 4.1.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.1.0
|
55
|
+
description: Soft delete records within rails
|
56
|
+
email:
|
57
|
+
- amedeiros0920@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".ruby-gemset"
|
64
|
+
- ".ruby-version"
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- lib/soft_delete_rails.rb
|
70
|
+
- lib/soft_delete_rails/has_soft_delete.rb
|
71
|
+
- lib/soft_delete_rails/scopes.rb
|
72
|
+
- lib/soft_delete_rails/version.rb
|
73
|
+
- soft_delete_rails.gemspec
|
74
|
+
- soft_delete_test
|
75
|
+
- test/configuration/database.yml
|
76
|
+
- test/configuration/schema.rb
|
77
|
+
- test/models/account.rb
|
78
|
+
- test/models/address.rb
|
79
|
+
- test/models/group.rb
|
80
|
+
- test/models/phone_number.rb
|
81
|
+
- test/models/user.rb
|
82
|
+
- test/soft_delete_rails_test.rb
|
83
|
+
- test/soft_delete_test
|
84
|
+
- test/test_helper.rb
|
85
|
+
homepage: ''
|
86
|
+
licenses:
|
87
|
+
- MIT
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 2.2.2
|
106
|
+
signing_key:
|
107
|
+
specification_version: 4
|
108
|
+
summary: Soft delete records within rails
|
109
|
+
test_files:
|
110
|
+
- test/configuration/database.yml
|
111
|
+
- test/configuration/schema.rb
|
112
|
+
- test/models/account.rb
|
113
|
+
- test/models/address.rb
|
114
|
+
- test/models/group.rb
|
115
|
+
- test/models/phone_number.rb
|
116
|
+
- test/models/user.rb
|
117
|
+
- test/soft_delete_rails_test.rb
|
118
|
+
- test/soft_delete_test
|
119
|
+
- test/test_helper.rb
|