paranoid 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Xspond Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,99 @@
1
+ h1. paranoid
2
+
3
+ h3. advice and disclaimer
4
+
5
+ You should never expect _any_ library to work or behave exactly how you want it to: test, test, test and file an issue if you have any problems. Bonus points if you include sample failing code. Extra bonus points if you send a pull request that implements a feature/fixes a bug.
6
+
7
+ h3. How did I get here?
8
+
9
+ Sometimes you want to delete something in ActiveRecord, but you realize you might need it later (for an undo feature, or just as a safety net, etc.). There are a plethora of plugins that accomplish this, the most famous of which was the venerable acts_as_paranoid which is great but not really actively developed any more. What's more, acts_as_paranoid was written for an older version of ActiveRecord. Is_paranoid was written for ActiveRecord 2.3 and default_scope. This however became, as the author stated, a mess of hacks to catch all the edge cases. *Paranoid* is an attempt to utilize ActiveRecord::Relation and JoinDependency in ActiveRecord 3 to do all the heavy lifting without using default_scope and with_exclusive_scope.
10
+
11
+ h3. How does it work?
12
+
13
+ You should read the specs, or the RDOC, or even the source itself (which is very readable), but for the lazy, here's the hand-holding:
14
+
15
+ You need ActiveRecord 3 and you need to properly install this gem. Then you need a model with a field to serve as a flag column on its database table. For this example we'll use a timestamp named "deleted_at". If that column is null, the item isn't deleted. If it has a timestamp, it should count as deleted.
16
+
17
+ So let's assume we have a model Automobile that has a deleted_at column on the automobiles table.
18
+
19
+ If you're working with Rails, in your Gemfile, add the following (you may want to change the version number).
20
+
21
+ <pre>
22
+ gem "paranoid", :require => 'paranoid', :version => ">= 0.1.0"
23
+ </pre>
24
+
25
+ Then in your ActiveRecord model
26
+
27
+ <pre>
28
+ class Automobile < ActiveRecord::Base
29
+ paranoid
30
+ end
31
+ </pre>
32
+
33
+ Now our automobiles are soft-deleteable.
34
+
35
+ <pre>
36
+ that_large_automobile = Automobile.create()
37
+ Automobile.count # => 1
38
+
39
+ that_large_automobile.destroy
40
+ Automobile.count # => 0
41
+ Automobile.count_with_destroyed # => 1
42
+
43
+ # where is that large automobile?
44
+ that_large_automobile = Automobile.find_with_destroyed(:all).first
45
+ that_large_automobile.restore
46
+ Automobile.count # => 1
47
+ </pre>
48
+
49
+ One thing to note, destroying is always undo-able, but deleting is not. This is a behavior difference between acts_as_paranoid and paranoid and the same as is_paranoid.
50
+
51
+ <pre>
52
+ Automobile.destroy_all
53
+ Automobile.count # => 0
54
+ Automobile.count_with_destroyed # => 1
55
+
56
+ Automobile.delete_all
57
+ Automobile.count_with_destroyed # => 0
58
+ # And you may say to yourself, "My god! What have I done?"
59
+ </pre>
60
+
61
+ Any find/count/sum/etc. _with_destroyed calls should work and you can also do find/count/sum/etc._destroyed_only.
62
+
63
+ h3. Specifying alternate rules for what should be considered destroyed
64
+
65
+ "deleted_at" as a timestamp is what acts_as_paranoid uses to define what is and isn't destroyed (see above), but you can specify alternate options with paranoid. In the paranoid line of your model you can specify the field, the value the field should have if the entry should count as destroyed, and the value the field should have if the entry is not destroyed. Consider the following models:
66
+
67
+ <pre>
68
+ class Pirate < ActiveRecord::Base
69
+ paranoid :field => [:alive, false, true]
70
+ end
71
+
72
+ class DeadPirate < ActiveRecord::Base
73
+ set_table_name :pirates
74
+ paranoid :field => [:alive, true, false]
75
+ end
76
+ </pre>
77
+
78
+ These two models share the same table, but when we are finding Pirates, we're only interested in those that are alive. To break it down, we specify :alive as our field to check, false as what the model field should be marked at when destroyed and true to what the field should be if they're not destroyed. DeadPirates are specified as the opposite. Check out the specs if you're still confused.
79
+
80
+ h3. Note about validates_uniqueness_of:
81
+
82
+ validates_uniqueness_of does not, by default, ignore items marked with a deleted_at (or other field name) flag. This is a behavior difference between paranoid and acts_as_paranoid and the same as is_paranoid. You can overcome this by specifying the field name you are using to mark destroyed items as your scope. Example:
83
+
84
+ <pre>
85
+ class Android < ActiveRecord::Base
86
+ validates_uniqueness_of :name, :scope => :deleted_at
87
+ paranoid
88
+ end
89
+ </pre>
90
+
91
+ And now the validates_uniqueness_of will ignore items that are destroyed.
92
+
93
+ h3. and you may ask yourself, where does that highway go to?
94
+
95
+ If you find any bugs, have any ideas of features you think are missing, or find things you're like to see work differently, feel free to file an issue or send a pull request.
96
+
97
+ h3. Thanks
98
+
99
+ Thanks to Rick Olson for acts_as_paranoid and to Jeffrey Chupp for is_paranoid.
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require "spec"
2
+ require "spec/rake/spectask"
3
+
4
+ Spec::Rake::SpecTask.new do |t|
5
+ t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
6
+ t.spec_files = FileList['spec/**/*_spec.rb']
7
+ end
8
+
9
+ begin
10
+ require 'jeweler'
11
+ Jeweler::Tasks.new do |s|
12
+ s.name = %q{paranoid}
13
+ s.summary = %q{Enable soft delete of ActiveRecord records. Based off defunct ActsAsParanoid and IsParanoid}
14
+ s.email = %q{github@xspond.com}
15
+ s.homepage = %q{http://github.com/xspond/paranoid/}
16
+ s.description = ""
17
+ s.authors = ["David Genord II"]
18
+ s.add_dependency('activerecord', '~> 3.0.0.beta')
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
23
+ end
24
+
25
+ task :default => :spec
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 0
4
+ :patch: 1
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'paranoid'
data/lib/paranoid.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'active_record'
2
+ require 'paranoid/base'
3
+ require 'paranoid/relation'
@@ -0,0 +1,90 @@
1
+ module Paranoid
2
+ module Base
3
+ def paranoid(opts = {})
4
+ return if paranoid?
5
+ @paranoid = true
6
+
7
+ opts[:field] ||= [:deleted_at, Proc.new{Time.now.utc}, nil]
8
+ class_inheritable_accessor :destroyed_field, :field_destroyed, :field_not_destroyed
9
+ self.destroyed_field, self.field_destroyed, self.field_not_destroyed = opts[:field]
10
+
11
+ extend ClassMethods
12
+ include InstanceMethods
13
+
14
+ class_eval do
15
+ class << self
16
+ delegate :with_destroyed, :to => :scoped
17
+ end
18
+ end
19
+ end
20
+
21
+ def paranoid?
22
+ @paranoid = false unless defined?(@paranoid)
23
+ @paranoid
24
+ end
25
+
26
+ module ClassMethods
27
+ def paranoid_condition
28
+ {destroyed_field => field_not_destroyed}
29
+ end
30
+
31
+ def paranoid_only_condition
32
+ ["#{table_name}.#{destroyed_field} IS NOT ?", field_not_destroyed]
33
+ end
34
+
35
+ def disable_paranoid
36
+ if block_given?
37
+ @paranoid = false
38
+ yield
39
+ end
40
+ ensure
41
+ @paranoid = true
42
+ end
43
+ end
44
+
45
+ module InstanceMethods
46
+ extend ActiveSupport::Concern
47
+
48
+ included do
49
+ alias_method_chain :create_or_update, :paranoid
50
+ end
51
+
52
+ def restore
53
+ set_destroyed(field_not_destroyed.respond_to?(:call) ? field_not_destroyed.call : field_not_destroyed)
54
+ @destroyed = false
55
+
56
+ self
57
+ end
58
+
59
+ # Override the default destroy to allow us to soft delete records.
60
+ # This preserves the before_destroy and after_destroy callbacks.
61
+ # Because this is also called internally by Model.destroy_all and
62
+ # the Model.destroy(id), we don't need to specify those methods
63
+ # separately.
64
+ def destroy
65
+ _run_destroy_callbacks do
66
+ set_destroyed(field_destroyed.respond_to?(:call) ? field_destroyed.call : field_destroyed)
67
+ @destroyed = true
68
+ end
69
+
70
+ self
71
+ end
72
+
73
+ protected
74
+
75
+ def create_or_update_with_paranoid
76
+ self.class.disable_paranoid { create_or_update_without_paranoid }
77
+ end
78
+
79
+ # Set the value for the destroyed field.
80
+ def set_destroyed(val)
81
+ self[destroyed_field] = val
82
+ updates = self.class.send(:sanitize_sql_for_assignment, {destroyed_field => val})
83
+ self.class.unscoped.with_destroyed.where(self.class.arel_table[self.class.primary_key].eq(id)).arel.update(updates)
84
+ @destroyed = true
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ ActiveRecord::Base.class_eval { extend Paranoid::Base }
@@ -0,0 +1,49 @@
1
+ module Paranoid
2
+ module Relation
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ alias_method_chain :arel, :paranoid
7
+ alias_method_chain :delete_all, :paranoid
8
+ end
9
+
10
+ def add_paranoid_condition?
11
+ @add_paranoid = true unless defined?(@add_paranoid)
12
+ @klass.paranoid? && @add_paranoid
13
+ end
14
+
15
+ def arel_with_paranoid
16
+ if add_paranoid_condition?
17
+ @arel ||= without_destroyed.arel_without_paranoid
18
+ else
19
+ arel_without_paranoid
20
+ end
21
+ end
22
+
23
+ def delete_all_with_paranoid(*args)
24
+ if add_paranoid_condition?
25
+ with_destroyed.delete_all_without_paranoid(*args)
26
+ else
27
+ delete_all_without_paranoid(*args)
28
+ end
29
+ end
30
+
31
+ def skip_paranoid_condition
32
+ @add_paranoid = false
33
+ end
34
+
35
+ def with_destroyed
36
+ spawn.tap {|relation| relation.skip_paranoid_condition }
37
+ end
38
+
39
+ def with_destroyed_only
40
+ where(@klass.paranoid_only_condition).tap {|relation| relation.skip_paranoid_condition }
41
+ end
42
+
43
+ def without_destroyed
44
+ where(@klass.paranoid_condition).tap {|relation| relation.skip_paranoid_condition }
45
+ end
46
+ end
47
+ end
48
+
49
+ ActiveRecord::Relation.class_eval { include Paranoid::Relation }
data/paranoid.gemspec ADDED
@@ -0,0 +1,60 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{paranoid}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["David Genord II"]
12
+ s.date = %q{2010-02-18}
13
+ s.description = %q{}
14
+ s.email = %q{github@xspond.com}
15
+ s.extra_rdoc_files = [
16
+ "README.textile"
17
+ ]
18
+ s.files = [
19
+ "MIT-LICENSE",
20
+ "README.textile",
21
+ "Rakefile",
22
+ "VERSION.yml",
23
+ "init.rb",
24
+ "lib/paranoid.rb",
25
+ "lib/paranoid/base.rb",
26
+ "lib/paranoid/relation.rb",
27
+ "paranoid.gemspec",
28
+ "spec/database.yml",
29
+ "spec/models.rb",
30
+ "spec/paranoid_spec.rb",
31
+ "spec/schema.rb",
32
+ "spec/spec.opts",
33
+ "spec/spec_helper.rb"
34
+ ]
35
+ s.homepage = %q{http://github.com/xspond/paranoid/}
36
+ s.rdoc_options = ["--charset=UTF-8"]
37
+ s.require_paths = ["lib"]
38
+ s.rubygems_version = %q{1.3.5}
39
+ s.summary = %q{Enable soft delete of ActiveRecord records. Based off defunct ActsAsParanoid and IsParanoid}
40
+ s.test_files = [
41
+ "spec/models.rb",
42
+ "spec/paranoid_spec.rb",
43
+ "spec/schema.rb",
44
+ "spec/spec_helper.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0.beta"])
53
+ else
54
+ s.add_dependency(%q<activerecord>, ["~> 3.0.0.beta"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<activerecord>, ["~> 3.0.0.beta"])
58
+ end
59
+ end
60
+
data/spec/database.yml ADDED
@@ -0,0 +1,3 @@
1
+ test:
2
+ :adapter: sqlite3
3
+ :database: paranoid.db
data/spec/models.rb ADDED
@@ -0,0 +1,135 @@
1
+ class Person < ActiveRecord::Base #:nodoc:
2
+ validates_uniqueness_of :name
3
+ has_many :androids, :foreign_key => :owner_id, :dependent => :destroy
4
+ end
5
+
6
+ class Android < ActiveRecord::Base #:nodoc:
7
+ paranoid
8
+ validates_uniqueness_of :name
9
+ has_many :components, :dependent => :destroy
10
+ has_one :sticker
11
+ has_many :memories, :foreign_key => 'parent_id'
12
+ has_many :dents
13
+ has_many :dings, :through => :dents
14
+ has_many :scratches, :through => :dents
15
+ has_and_belongs_to_many :places
16
+
17
+ # this code is to ensure that our destroy and restore methods
18
+ # work without triggering before/after_update callbacks
19
+ before_update :raise_hell
20
+ def raise_hell
21
+ raise "hell"
22
+ end
23
+ end
24
+
25
+ class Dent < ActiveRecord::Base #:nodoc:
26
+ paranoid
27
+ belongs_to :android
28
+ has_many :dings
29
+ has_many :scratches
30
+ end
31
+
32
+ class Ding < ActiveRecord::Base #:nodoc:
33
+ paranoid :field => [:not_deleted, true, false]
34
+ belongs_to :dent
35
+ end
36
+
37
+ class Scratch < ActiveRecord::Base #:nodoc:
38
+ paranoid
39
+ belongs_to :dent
40
+ end
41
+
42
+ class Component < ActiveRecord::Base #:nodoc:
43
+ paranoid
44
+ belongs_to :android, :dependent => :destroy
45
+ has_many :sub_components, :dependent => :destroy
46
+ NEW_NAME = 'Something Else!'
47
+
48
+ after_destroy :change_name
49
+ def change_name
50
+ self.update_attribute(:name, NEW_NAME)
51
+ end
52
+ end
53
+
54
+ class SubComponent < ActiveRecord::Base #:nodoc:
55
+ paranoid
56
+ belongs_to :component, :dependent => :destroy
57
+ end
58
+
59
+ class Memory < ActiveRecord::Base #:nodoc:
60
+ paranoid
61
+ belongs_to :android, :class_name => "Android", :foreign_key => "parent_id"
62
+ end
63
+
64
+ class Sticker < ActiveRecord::Base #:nodoc:
65
+ MM_NAME = "You've got method_missing"
66
+
67
+ # this simply serves to ensure that we don't break method_missing
68
+ # if it is implemented on a class and called before is_paranoid
69
+ def method_missing name, *args, &block
70
+ self.name = MM_NAME
71
+ end
72
+
73
+ paranoid
74
+ belongs_to :android
75
+ end
76
+
77
+ class AndroidWithScopedUniqueness < ActiveRecord::Base #:nodoc:
78
+ set_table_name :androids
79
+ validates_uniqueness_of :name, :scope => :deleted_at
80
+ paranoid
81
+ end
82
+
83
+ class Place < ActiveRecord::Base #:nodoc:
84
+ paranoid
85
+ has_and_belongs_to_many :androids
86
+ end
87
+
88
+ class AndroidsPlaces < ActiveRecord::Base #:nodoc:
89
+ end
90
+
91
+ class Ninja < ActiveRecord::Base #:nodoc:
92
+ validates_uniqueness_of :name, :scope => :visible
93
+ paranoid :field => [:visible, false, true]
94
+
95
+ alias_method :vanish, :destroy
96
+ end
97
+
98
+ class Pirate < ActiveRecord::Base #:nodoc:
99
+ paranoid :field => [:alive, false, true]
100
+ end
101
+
102
+ class DeadPirate < ActiveRecord::Base #:nodoc:
103
+ set_table_name :pirates
104
+ paranoid :field => [:alive, true, false]
105
+ end
106
+
107
+ class RandomPirate < ActiveRecord::Base #:nodoc:
108
+ set_table_name :pirates
109
+
110
+ after_destroy :raise_an_error
111
+ def raise_an_error
112
+ raise 'after_destroy works'
113
+ end
114
+ end
115
+
116
+ class UndestroyablePirate < ActiveRecord::Base #:nodoc:
117
+ set_table_name :pirates
118
+ paranoid :field => [:alive, false, true]
119
+
120
+ before_destroy :ret_false
121
+ def ret_false
122
+ false
123
+ end
124
+ end
125
+
126
+ class Uuid < ActiveRecord::Base #:nodoc:
127
+ set_primary_key "uuid"
128
+
129
+ before_create :set_uuid
130
+ def set_uuid
131
+ self.uuid = "295b3430-85b8-012c-cfe4-002332cf7d5e"
132
+ end
133
+
134
+ paranoid
135
+ end
@@ -0,0 +1,99 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/models')
3
+
4
+ LUKE = 'Luke Skywalker'
5
+
6
+ describe Paranoid do
7
+ before(:each) do
8
+ Sticker.delete_all
9
+ Place.delete_all
10
+ Android.delete_all
11
+ Person.delete_all
12
+ Component.delete_all
13
+
14
+ @luke = Person.create(:name => LUKE)
15
+ @r2d2 = Android.create(:name => 'R2D2', :owner_id => @luke.id)
16
+ @c3p0 = Android.create(:name => 'C3P0', :owner_id => @luke.id)
17
+
18
+ @r2d2.components.create(:name => 'Rotors')
19
+
20
+ @r2d2.memories.create(:name => 'A pretty sunset')
21
+ @c3p0.sticker = Sticker.create(:name => 'OMG, PONIES!')
22
+ @tatooine = Place.create(:name => "Tatooine")
23
+ @r2d2.places << @tatooine
24
+ end
25
+
26
+ it 'should recognize a class as paranoid' do
27
+ Person.paranoid?.should be_false
28
+ Place.paranoid?.should be_true
29
+ end
30
+
31
+ it 'should hide destroyed records' do
32
+ @tatooine.update_attribute('deleted_at', Time.now)
33
+ Place.first(:conditions => {:name => 'Tatooine'}).should be_nil
34
+ end
35
+
36
+ it 'should reveal destroyed records when with_destroyed' do
37
+ @tatooine.update_attribute('deleted_at', Time.now)
38
+ Place.with_destroyed.first(:conditions => {:name => 'Tatooine'}).should_not be_nil
39
+ end
40
+
41
+ it 'should restore the destroyed record' do
42
+ @tatooine.update_attribute('deleted_at', Time.now)
43
+
44
+ @tatooine = Place.with_destroyed.first(:conditions => {:name => 'Tatooine'})
45
+ @tatooine.restore
46
+
47
+ Place.first(:conditions => {:name => 'Tatooine'}).should_not be_nil
48
+ end
49
+
50
+ it 'should soft delete paranoid records' do
51
+ @tatooine.destroy
52
+
53
+ record = Place.with_destroyed.first(:conditions => {:name => 'Tatooine'})
54
+ record.should_not be_nil
55
+ record.deleted_at.should_not be_nil
56
+ end
57
+
58
+ it 'should mark the record destroyed' do
59
+ @tatooine.destroy
60
+ @tatooine.destroyed?.should be_true
61
+ end
62
+
63
+ it 'should set the deleted_field' do
64
+ @tatooine.destroy
65
+ @tatooine.deleted_at.should_not be_nil
66
+ end
67
+
68
+ describe 'for alternate field information' do
69
+ before(:each) do
70
+ Ninja.delete_all
71
+ @ninja = Ninja.create(:name => 'Steve')
72
+ end
73
+
74
+ it 'should vanish the ninja' do
75
+ @ninja.destroy
76
+
77
+ record = Ninja.first(:conditions => {:name => 'Steve'})
78
+ record.should be_nil
79
+ end
80
+
81
+ it 'should not delete the ninja' do
82
+ @ninja.destroy
83
+
84
+ record = Ninja.with_destroyed.first(:conditions => {:name => 'Steve'})
85
+ record.should_not be_nil
86
+ record.visible.should be_false
87
+ end
88
+
89
+ it 'should mark the ninja vanished' do
90
+ @ninja.destroy
91
+ @ninja.destroyed?.should be_true
92
+ end
93
+
94
+ it 'should set visible to false' do
95
+ @ninja.destroy
96
+ @ninja.visible.should be_false
97
+ end
98
+ end
99
+ end
data/spec/schema.rb ADDED
@@ -0,0 +1,86 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table "androids", :force => true do |t|
3
+ t.string "name"
4
+ t.integer "owner_id"
5
+ t.datetime "deleted_at"
6
+ t.datetime "created_at"
7
+ t.datetime "updated_at"
8
+ end
9
+
10
+ create_table "dents", :force => true do |t|
11
+ t.integer "android_id"
12
+ t.string "description"
13
+ t.datetime "deleted_at"
14
+ end
15
+
16
+ create_table "dings", :force => true do |t|
17
+ t.integer "dent_id"
18
+ t.string "description"
19
+ t.boolean "not_deleted"
20
+ end
21
+
22
+ create_table "scratches", :force => true do |t|
23
+ t.integer "dent_id"
24
+ t.string "description"
25
+ t.datetime "deleted_at"
26
+ end
27
+
28
+ create_table "androids_places", :force => true, :id => false do |t|
29
+ t.integer "android_id"
30
+ t.integer "place_id"
31
+ end
32
+
33
+ create_table "places", :force => true do |t|
34
+ t.string "name"
35
+ t.datetime "deleted_at"
36
+ end
37
+
38
+ create_table "people", :force => true do |t|
39
+ t.string "name"
40
+ t.datetime "created_at"
41
+ t.datetime "updated_at"
42
+ end
43
+
44
+ create_table "components", :force => true do |t|
45
+ t.string "name"
46
+ t.integer "android_id"
47
+ t.datetime "deleted_at"
48
+ t.datetime "created_at"
49
+ t.datetime "updated_at"
50
+ end
51
+
52
+ create_table "sub_components", :force => true do |t|
53
+ t.string "name"
54
+ t.integer "component_id"
55
+ t.datetime "deleted_at"
56
+ end
57
+
58
+ create_table "memories", :force => true do |t|
59
+ t.string "name"
60
+ t.integer "parent_id"
61
+ t.datetime "deleted_at"
62
+ end
63
+
64
+ create_table "stickers", :force => true do |t|
65
+ t.string "name"
66
+ t.integer "android_id"
67
+ t.datetime "deleted_at"
68
+ end
69
+
70
+ create_table "ninjas", :force => true do |t|
71
+ t.string "name"
72
+ t.boolean "visible", :default => false
73
+ end
74
+
75
+ create_table "pirates", :force => true do |t|
76
+ t.string "name"
77
+ t.boolean "alive", :default => true
78
+ end
79
+
80
+ create_table "uuids", :id => false, :force => true do |t|
81
+ t.string "uuid", :limit => 36, :primary => true
82
+ t.string "name"
83
+ t.datetime "deleted_at"
84
+ end
85
+
86
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'active_record'
5
+ require 'paranoid'
6
+ require 'yaml'
7
+ require 'spec'
8
+
9
+ def connect(environment)
10
+ conf = YAML::load(File.open(File.dirname(__FILE__) + '/database.yml'))
11
+ ActiveRecord::Base.establish_connection(conf[environment])
12
+ end
13
+
14
+ # Open ActiveRecord connection
15
+ connect('test')
16
+
17
+ original_stdout = $stdout
18
+ $stdout = StringIO.new
19
+
20
+ begin
21
+ load(File.dirname(__FILE__) + "/schema.rb")
22
+ ensure
23
+ $stdout = original_stdout
24
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paranoid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - David Genord II
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-18 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 3.0.0.beta
24
+ version:
25
+ description: ""
26
+ email: github@xspond.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.textile
33
+ files:
34
+ - MIT-LICENSE
35
+ - README.textile
36
+ - Rakefile
37
+ - VERSION.yml
38
+ - init.rb
39
+ - lib/paranoid.rb
40
+ - lib/paranoid/base.rb
41
+ - lib/paranoid/relation.rb
42
+ - paranoid.gemspec
43
+ - spec/database.yml
44
+ - spec/models.rb
45
+ - spec/paranoid_spec.rb
46
+ - spec/schema.rb
47
+ - spec/spec.opts
48
+ - spec/spec_helper.rb
49
+ has_rdoc: true
50
+ homepage: http://github.com/xspond/paranoid/
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options:
55
+ - --charset=UTF-8
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.5
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Enable soft delete of ActiveRecord records. Based off defunct ActsAsParanoid and IsParanoid
77
+ test_files:
78
+ - spec/models.rb
79
+ - spec/paranoid_spec.rb
80
+ - spec/schema.rb
81
+ - spec/spec_helper.rb