soft_delete_rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |task|
5
+ task.libs << 'test'
6
+ task.test_files = FileList['test/*_test.rb']
7
+ end
8
+
9
+ task :default => [:test]
10
+
@@ -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,3 @@
1
+ module SoftDeleteRails
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,6 @@
1
+ require 'soft_delete_rails/version'
2
+ require 'soft_delete_rails/scopes'
3
+ require 'soft_delete_rails/has_soft_delete'
4
+
5
+ # Include our model mixin
6
+ ActiveRecord::Base.send(:include, SoftDeleteRails::Model)
@@ -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,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: soft_delete_test
@@ -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
@@ -0,0 +1,4 @@
1
+ class Account < ActiveRecord::Base
2
+ validates :name, presence: true
3
+ has_soft_delete default_scope: false, validate: false
4
+ end
@@ -0,0 +1,4 @@
1
+ class Address < ActiveRecord::Base
2
+ belongs_to :user
3
+ has_soft_delete
4
+ end
@@ -0,0 +1,5 @@
1
+ class Group < ActiveRecord::Base
2
+ has_many :users, dependent: :destroy
3
+ validates :name, presence: :true
4
+ has_soft_delete
5
+ end
@@ -0,0 +1,3 @@
1
+ class PhoneNumber < ActiveRecord::Base
2
+ belongs_to :user
3
+ end
@@ -0,0 +1,6 @@
1
+ class User < ActiveRecord::Base
2
+ belongs_to :group
3
+ has_one :phone_number, dependent: :destroy
4
+ has_one :address, dependent: :destroy
5
+ has_soft_delete
6
+ end
@@ -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
@@ -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