affected_on_destroy 0.0.2

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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Marcin Urbanski
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.
@@ -0,0 +1,91 @@
1
+ # affected_on_destroy
2
+
3
+ affected_on_destroy is a simple Rails plugin that recursively reflects on defined associations and lets you know which records will be deleted/nullified when using <b>:dependent => :destroy</b> or <b>:dependent => :nullify</b>.
4
+
5
+ ## Installation
6
+
7
+ config.gem 'murbanski-affected_on_destroy', :lib => 'affected_on_destroy', :source => 'http://gems.github.com'
8
+
9
+
10
+ ## Usage
11
+
12
+ schema.rb:
13
+
14
+ create_table "users", :force => true do |t|
15
+ t.string "login"
16
+ t.string "password"
17
+ t.datetime "created_at"
18
+ t.datetime "updated_at"
19
+ end
20
+
21
+ create_table "blogs", :force => true do |t|
22
+ t.integer "user_id"
23
+ t.string "name"
24
+ t.datetime "created_at"
25
+ t.datetime "updated_at"
26
+ end
27
+
28
+ create_table "posts", :force => true do |t|
29
+ t.integer "blog_id"
30
+ t.text "content"
31
+ t.datetime "created_at"
32
+ t.datetime "updated_at"
33
+ end
34
+
35
+
36
+
37
+
38
+ models:
39
+ class User < ActiveRecord::Base
40
+ has_many :blogs, :dependent => :destroy
41
+ end
42
+
43
+ class Blog < ActiveRecord::Base
44
+ belongs_to :user
45
+ has_many :posts, :dependent => :nullify
46
+ end
47
+
48
+ class Post < ActiveRecord::Base
49
+ belongs_to :blog
50
+ end
51
+
52
+
53
+ Sample script/console session:
54
+ >> marcin = User.create(:login => 'marcin', :password => 'my_pass')
55
+ => #<User id: 1, login: "marcin", password: "my_pass", created_at: "2009-06-26 01:47:36", updated_at: "2009-06-26 01:47:36">
56
+
57
+ >> blog = marcin.blogs.create(:name => 'My Ruby Blog')
58
+ => #<Blog id: 1, user_id: 1, name: "My Ruby Blog", created_at: "2009-06-26 01:47:57", updated_at: "2009-06-26 01:47:57">
59
+
60
+ >> blog.posts.create(:content => 'Ruby tricks #1')
61
+ => #<Post id: 1, blog_id: 1, content: "Ruby tricks #1", created_at: "2009-06-26 01:48:40", updated_at: "2009-06-26 01:48:40">
62
+ >> blog.posts.create(:content => 'Ruby tricks #2')
63
+ => #<Post id: 2, blog_id: 1, content: "Ruby tricks #2", created_at: "2009-06-26 01:48:45", updated_at: "2009-06-26 01:48:45">
64
+
65
+ What records will be affected when we destroy user 'marcin'?
66
+ >> marcin.affected_on_destroy
67
+ => [#<Blog id: 1, user_id: 1, name: "My Ruby Blog", created_at: "2009-06-26 01:47:57", updated_at: "2009-06-26 01:47:57">,
68
+ #<Post id: 1, blog_id: 1, content: "Ruby tricks #1", created_at: "2009-06-26 01:48:40", updated_at: "2009-06-26 01:48:40">,
69
+ #<Post id: 2, blog_id: 1, content: "Ruby tricks #2", created_at: "2009-06-26 01:48:45", updated_at: "2009-06-26 01:48:45">]
70
+
71
+ A bit cleaner summary - only with model name and id:
72
+ >> puts marcin.affected_on_destroy_info
73
+ Blog 1
74
+ Post 1
75
+ Post 2
76
+ => nil
77
+
78
+ Which models are affected when destroying user?
79
+ >> User.affected_on_destroy
80
+ => ["Blog", "Post"]
81
+
82
+ Same for blog:
83
+ >> Blog.affected_on_destroy
84
+ => ["Post"]
85
+
86
+
87
+ ## Rails Version
88
+
89
+ Works on Rails 2.3 and 2.2
90
+
91
+
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "affected_on_destroy"
8
+ gem.summary = %Q{Rails plugin showing which related records will be deleted from DB when :dependent => :destroy is used}
9
+ gem.description = %Q{Rails plugin showing which related records will be deleted from DB when :dependent => :destroy is used}
10
+ gem.email = "marcin@urbanski.vdl.pl"
11
+ gem.homepage = "http://github.com/murbanski/affected_on_destroy"
12
+ gem.authors = ["Marcin Urbanski"]
13
+ gem.files = FileList["[A-Z]*", "{rails,lib}/**/*"]
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/*_test.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/*_test.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ if File.exist?('VERSION.yml')
47
+ config = YAML.load(File.read('VERSION.yml'))
48
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
49
+ else
50
+ version = ""
51
+ end
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "affected_on_destroy #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
58
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
@@ -0,0 +1,57 @@
1
+
2
+
3
+ module AffectedOnDestroy
4
+
5
+ def self.included(klass)
6
+ klass.extend ClassMethods
7
+ end
8
+
9
+
10
+ module ClassMethods
11
+ def dependent_associations
12
+ associations = self.reflect_on_all_associations(:has_many) + self.reflect_on_all_associations(:has_one)
13
+ associations.select {|a| a.options.has_key?(:dependent)}
14
+ end
15
+
16
+
17
+ # TODO: infinite recursion: create array already_inspected_associations
18
+ # User.affected_on_destroy # => ["Post", "Comments", "Ratings"]
19
+ def affected_on_destroy
20
+ returning affected = [] do
21
+ dependent_associations.map do |assoc|
22
+ affected << assoc.class_name
23
+ affected << assoc.class_name.constantize.affected_on_destroy
24
+ end
25
+ end.flatten.uniq.sort
26
+ end
27
+ end
28
+
29
+
30
+ # u = User.first
31
+ # u.affected_on_destroy # => [ #<Post id: 25>, #<Comment id: 10, post_id: 25>, #<Rating id: 3, post_id: 25>]
32
+ def affected_on_destroy
33
+ affected_objects = []
34
+ self.class.dependent_associations.each do |assoc|
35
+ next if (associated_relation = self.send(assoc.name)).blank?
36
+ if assoc.macro == :has_one
37
+ affected_objects << associated_relation
38
+ affected_objects << associated_relation.affected_on_destroy
39
+ elsif assoc.macro == :has_many
40
+ associated_relation.each do |associated_object|
41
+ affected_objects << associated_object
42
+ affected_objects << associated_object.affected_on_destroy
43
+ end
44
+ end
45
+ end
46
+
47
+ affected_objects.flatten.uniq.sort_by {|elem| elem.class.to_s }
48
+ end
49
+
50
+ def affected_on_destroy_info
51
+ self.affected_on_destroy.map{|obj| "#{obj.class.to_s} #{obj.id}"}
52
+ end
53
+
54
+ end
55
+
56
+
57
+ ActiveRecord::Base.send :include, AffectedOnDestroy
@@ -0,0 +1 @@
1
+ require 'affected_on_destroy'
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: affected_on_destroy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Marcin Urbanski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-26 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Rails plugin showing which related records will be deleted from DB when :dependent => :destroy is used
17
+ email: marcin@urbanski.vdl.pl
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.md
25
+ files:
26
+ - LICENSE
27
+ - README.md
28
+ - Rakefile
29
+ - VERSION
30
+ - lib/affected_on_destroy.rb
31
+ - rails/init.rb
32
+ has_rdoc: true
33
+ homepage: http://github.com/murbanski/affected_on_destroy
34
+ post_install_message:
35
+ rdoc_options:
36
+ - --charset=UTF-8
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project:
54
+ rubygems_version: 1.3.1
55
+ signing_key:
56
+ specification_version: 2
57
+ summary: Rails plugin showing which related records will be deleted from DB when :dependent => :destroy is used
58
+ test_files: []
59
+