JackDanger-permanent_records 1.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.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,18 @@
1
+ MIT-LICENSE
2
+ Manifest.txt
3
+ README
4
+ Rakefile
5
+ init.rb
6
+ install.rb
7
+ lib/permanent_records.rb
8
+ tasks/permanent_records_tasks.rake
9
+ test/cached_values_test.rb
10
+ test/database.yml
11
+ test/hole.rb
12
+ test/kitty.rb
13
+ test/mole.rb
14
+ test/muskrat.rb
15
+ test/permanent_records_test.rb
16
+ test/schema.rb
17
+ test/test_helper.rb
18
+ uninstall.rb
data/README ADDED
@@ -0,0 +1,22 @@
1
+ PermanentRecords
2
+ ================
3
+
4
+ This plugin prevents any of your records from being destroyed casually.
5
+ Any model with a deleted_at datetime column will have that column set rather than being deleted.
6
+
7
+ Usage
8
+ =======
9
+
10
+ User.find(3).destroy # sets the 'deleted_at' attribute to Time.now and returns a frozen record
11
+ User.find(3).destroy(:force) # executes the real destroy method, the record will be removed from the database
12
+ User.delete_all # bye bye everything
13
+
14
+ There are also two named scopes provided for easily searching deleted and not deleted records:
15
+
16
+ User.send :with_deleted { User.find(:all) } # only returns deleted records.
17
+ User.send :with_not_deleted { User.find(:all) } # you guessed it.
18
+
19
+ These are named so as to work smoothly with other scoping plugins like scope_out.
20
+
21
+
22
+ Copyright (c) 2008 Jack Danger Canty of adPickles Inc., released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require File.dirname(__FILE__) + '/lib/permanent_records'
6
+
7
+ Hoe.new('permanent_records', PermanentRecords::VERSION) do |p|
8
+ p.summary = "Soft-delete your ActiveRecord data."
9
+ p.developer('Jack Danger Canty', 'gems@6brand.com')
10
+ end
11
+
12
+ # vim: syntax=Ruby
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'permanent_records'
2
+
3
+ ActiveRecord::Base.send :include, PermanentRecords
data/install.rb ADDED
File without changes
@@ -0,0 +1,86 @@
1
+ module PermanentRecords
2
+ VERSION = '1.0.1'
3
+ def self.included(base)
4
+ if base.respond_to?(:named_scope)
5
+ base.named_scope :deleted, :conditions => {:deleted_at => true}
6
+ base.named_scope :not_deleted, :conditions => { :deleted_at => nil }
7
+ else
8
+ base.extend LegacyScopes
9
+ end
10
+ base.send :include, InstanceMethods
11
+ base.define_callbacks :before_revive, :after_revive
12
+ base.alias_method_chain :destroy, :permanent_record_force
13
+ base.alias_method_chain :destroy_without_callbacks, :permanent_record
14
+ end
15
+
16
+ module LegacyScopes
17
+ def with_deleted
18
+ with_scope :find => {:conditions => "#{quoted_table_name}.deleted_at IS NOT NULL"} do
19
+ yield
20
+ end
21
+ end
22
+
23
+ def with_not_deleted
24
+ with_scope :find => {:conditions => "#{quoted_table_name}.deleted_at IS NULL"} do
25
+ yield
26
+ end
27
+ end
28
+
29
+ # this next bit is basically stolen from the scope_out plugin
30
+ [:deleted, :not_deleted].each do |name|
31
+ define_method "find_#{name}" do |*args|
32
+ send("with_#{name}") { find(*args) }
33
+ end
34
+
35
+ define_method "count_#{name}" do |*args|
36
+ send("with_#{name}") { count(*args) }
37
+ end
38
+
39
+ define_method "calculate_#{name}" do |*args|
40
+ send("with_#{name}") { calculate(*args) }
41
+ end
42
+
43
+ define_method "find_all_#{name}" do |*args|
44
+ send("with_#{name}") { find(:all, *args) }
45
+ end
46
+ end
47
+ end
48
+
49
+ module InstanceMethods
50
+
51
+ def is_permanent?
52
+ respond_to?(:deleted_at)
53
+ end
54
+
55
+ def deleted?
56
+ deleted_at if is_permanent?
57
+ end
58
+
59
+ def revive
60
+ run_callbacks :before_revive
61
+ set_deleted_at nil
62
+ run_callbacks :after_revive
63
+ self
64
+ end
65
+
66
+ def set_deleted_at(value)
67
+ return self unless is_permanent?
68
+ record = self.class.find(id)
69
+ record.update_attribute(:deleted_at, value)
70
+ @attributes, @attributes_cache = record.attributes, record.attributes
71
+ end
72
+
73
+ def destroy_with_permanent_record_force(force = nil)
74
+ @force_permanent_record_destroy = (:force == force)
75
+ destroy_without_permanent_record_force
76
+ end
77
+
78
+ def destroy_without_callbacks_with_permanent_record
79
+ return destroy_without_callbacks_without_permanent_record if @force_permanent_record_destroy || !is_permanent?
80
+ unless deleted? || new_record?
81
+ set_deleted_at Time.now
82
+ end
83
+ self
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :permanent_records do
3
+ # # Task goes here
4
+ # end
data/test/database.yml ADDED
@@ -0,0 +1,18 @@
1
+ sqlite:
2
+ :adapter: sqlite
3
+ :dbfile: plugin.sqlite.db
4
+ sqlite3:
5
+ :adapter: sqlite3
6
+ :dbfile: ":memory:"
7
+ postgresql:
8
+ :adapter: postgresql
9
+ :username: postgres
10
+ :password: postgres
11
+ :database: plugin_test
12
+ :min_messages: ERROR
13
+ mysql:
14
+ :adapter: mysql
15
+ :host: localhost
16
+ :username: rails
17
+ :password:
18
+ :database: plugin_test
data/test/hole.rb ADDED
@@ -0,0 +1,6 @@
1
+ class Hole < ActiveRecord::Base
2
+ # muskrats are permanent
3
+ has_many :muskrats, :dependent => :destroy
4
+ # moles are not permanent
5
+ has_many :moles, :dependent => :destroy
6
+ end
data/test/kitty.rb ADDED
@@ -0,0 +1,2 @@
1
+ class Kitty < ActiveRecord::Base
2
+ end
data/test/mole.rb ADDED
@@ -0,0 +1,3 @@
1
+ class Mole < ActiveRecord::Base
2
+ belongs_to :hole
3
+ end
data/test/muskrat.rb ADDED
@@ -0,0 +1,3 @@
1
+ class Muskrat < ActiveRecord::Base
2
+ belongs_to :hole
3
+ end
@@ -0,0 +1,110 @@
1
+ require 'test/unit'
2
+ require File.expand_path(File.dirname(__FILE__) + "/test_helper")
3
+
4
+ %w(hole mole muskrat kitty).each do |a|
5
+ require File.expand_path(File.dirname(__FILE__) + "/" + a)
6
+ end
7
+
8
+ class PermanentRecordsTest < Test::Unit::TestCase
9
+
10
+ def setup
11
+ super
12
+ Muskrat.delete_all
13
+ @active = Muskrat.create!(:name => 'Wakko')
14
+ @deleted = Muskrat.create!(:name => 'Yakko', :deleted_at => 4.days.ago)
15
+ @the_girl = Muskrat.create!(:name => 'Dot')
16
+ Kitty.delete_all
17
+ @kitty = Kitty.create!(:name => 'Meow Meow')
18
+ @hole = Hole.create(:number => 14)
19
+ @mole = @hole.muskrats.create(:name => "Steady Rat")
20
+ @mole = @hole.moles.create(:name => "Grabowski")
21
+ end
22
+
23
+ def teardown
24
+ setup
25
+ end
26
+
27
+ def test_destroy_should_return_the_record
28
+ muskrat = @active
29
+ assert_equal muskrat, muskrat.destroy
30
+ end
31
+
32
+ def test_revive_should_return_the_record
33
+ muskrat = @deleted
34
+ assert_equal muskrat, muskrat.destroy
35
+ end
36
+
37
+ def test_destroy_should_set_deleted_at_attribute
38
+ assert @active.destroy.deleted_at
39
+ end
40
+
41
+ def test_destroy_should_save_deleted_at_attribute
42
+ assert Muskrat.find(@active.destroy.id).deleted_at
43
+ end
44
+
45
+ def test_destroy_should_not_really_remove_the_record
46
+ assert Muskrat.find(@active.destroy.id)
47
+ end
48
+
49
+ def test_destroy_should_recognize_a_force_parameter
50
+ assert_raises(ActiveRecord::RecordNotFound) { @active.destroy(:force).reload }
51
+ end
52
+
53
+ def test_destroy_should_ignore_other_parameters
54
+ assert Muskrat.find(@active.destroy(:hula_dancer).id)
55
+ end
56
+
57
+ def test_revive_should_unfreeze_record
58
+ assert !@deleted.revive.frozen?
59
+ end
60
+
61
+ def test_revive_should_unset_deleted_at
62
+ assert !@deleted.revive.deleted_at
63
+ end
64
+
65
+ def test_revive_should_make_deleted_return_false
66
+ assert !@deleted.revive.deleted?
67
+ end
68
+
69
+ def test_deleted_returns_true_for_deleted_records
70
+ assert @deleted.deleted?
71
+ end
72
+
73
+ def test_destroy_returns_record_with_modified_attributes
74
+ assert @active.destroy.deleted?
75
+ end
76
+
77
+ def test_revive_and_destroy_should_be_chainable
78
+ assert @active.destroy.revive.destroy.destroy.revive.revive.destroy.deleted?
79
+ assert !@deleted.destroy.revive.revive.destroy.destroy.revive.deleted?
80
+ end
81
+
82
+ def test_with_deleted_limits_scope_to_deleted_records
83
+ assert Muskrat.deleted.all?(&:deleted?)
84
+ end
85
+
86
+ def test_with_not_deleted_limits_scope_to_not_deleted_records
87
+ assert !Muskrat.not_deleted.any?(&:deleted?)
88
+ end
89
+
90
+ def test_models_without_a_deleted_at_column_should_destroy_as_normal
91
+ assert_raises(ActiveRecord::RecordNotFound) {@kitty.destroy.reload}
92
+ end
93
+
94
+ def test_dependent_non_permanent_records_should_be_destroyed
95
+ assert @hole.is_permanent?
96
+ assert !@hole.moles.first.is_permanent?
97
+ assert_difference "Mole.count", -1 do
98
+ @hole.destroy
99
+ end
100
+ end
101
+
102
+ def test_dependent_permanent_records_should_be_marked_as_deleted
103
+ assert @hole.is_permanent?
104
+ assert @hole.muskrats.first.is_permanent?
105
+ assert_no_difference "Muskrat.count" do
106
+ @hole.destroy
107
+ end
108
+ assert @hole.muskrats.first.deleted?
109
+ end
110
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,23 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+
3
+ create_table :muskrats do |t|
4
+ t.column :name, :string
5
+ t.column :deleted_at, :datetime
6
+ t.references :hole
7
+ end
8
+
9
+ create_table :kitties do |t|
10
+ t.column :name, :string
11
+ end
12
+
13
+ create_table :holes do |t|
14
+ t.integer :number
15
+ t.datetime :deleted_at
16
+ end
17
+
18
+ create_table :moles do |t|
19
+ t.string :name
20
+ t.references :hole
21
+ end
22
+
23
+ end
@@ -0,0 +1,39 @@
1
+ # Include this file in your test by copying the following line to your test:
2
+ # require File.expand_path(File.dirname(__FILE__) + "/test_helper")
3
+
4
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
5
+ RAILS_ROOT = File.dirname(__FILE__)
6
+
7
+ require 'rubygems'
8
+ require 'test/unit'
9
+ require 'active_record'
10
+ require 'active_record/fixtures'
11
+ require "#{File.dirname(__FILE__)}/../init"
12
+ require File.expand_path(File.dirname(__FILE__) + "/muskrat")
13
+
14
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
15
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
16
+ ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite3'])
17
+
18
+ load(File.dirname(__FILE__) + "/schema.rb") if File.exist?(File.dirname(__FILE__) + "/schema.rb")
19
+
20
+ Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
21
+ $LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
22
+
23
+ class Test::Unit::TestCase #:nodoc:
24
+ # def create_fixtures(*table_names)
25
+ # if block_given?
26
+ # Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names) { yield }
27
+ # else
28
+ # Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names)
29
+ # end
30
+ # end
31
+
32
+ # Turn off transactional fixtures if you're working with MyISAM tables in MySQL
33
+ self.use_transactional_fixtures = true
34
+
35
+ # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
36
+ self.use_instantiated_fixtures = false
37
+
38
+ # Add more helper methods to be used by all tests here...
39
+ end
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: JackDanger-permanent_records
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jack Danger Canty
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-19 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.11.0
24
+ version:
25
+ description:
26
+ email:
27
+ - gems@6brand.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - Manifest.txt
34
+ files:
35
+ - MIT-LICENSE
36
+ - Manifest.txt
37
+ - README
38
+ - Rakefile
39
+ - init.rb
40
+ - install.rb
41
+ - lib/permanent_records.rb
42
+ - tasks/permanent_records_tasks.rake
43
+ - test/cached_values_test.rb
44
+ - test/database.yml
45
+ - test/hole.rb
46
+ - test/kitty.rb
47
+ - test/mole.rb
48
+ - test/muskrat.rb
49
+ - test/permanent_records_test.rb
50
+ - test/schema.rb
51
+ - test/test_helper.rb
52
+ - uninstall.rb
53
+ has_rdoc: true
54
+ homepage:
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --main
58
+ - README.txt
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ requirements: []
74
+
75
+ rubyforge_project: permanent_records
76
+ rubygems_version: 1.2.0
77
+ signing_key:
78
+ specification_version: 2
79
+ summary: Soft-delete your ActiveRecord data.
80
+ test_files:
81
+ - test/test_helper.rb