prevent_destroy_if_any 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in prevent_destroy_if_any.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ prevent_destroy_if_any
2
+ ===
3
+
4
+ This plugin adds ActiveRecord models a way to prevent destroy if specified `has_many`, `has_one` and/or `belongs_to` associations are present. This is achieved by adding a `before_destroy` callback that aborts the destroy and adds a base error on the instance when detecting associations.
5
+
6
+ It's inspired from [this stackoverflow answer](http://stackoverflow.com/questions/4054112/how-do-i-prevent-deletion-of-parent-if-it-has-child-records/4054170#4054170) and was created to factorize this solution when you need it for various models in an application.
7
+
8
+ It has been tested only with ActiveRecord 3.
9
+
10
+ Installation
11
+ ---
12
+
13
+ `gem install prevent_destroy_if_any`
14
+
15
+ If you use Bundler, edit your `Gemfile` to add `gem 'prevent_destroy_if_any'`.
16
+
17
+
18
+ Example usage
19
+ ---
20
+
21
+ A Person model for which you want to prevent destroy when it has an associated user, projects or public profile. Destroy will work if it has associated logs.
22
+
23
+ class Person < ActiveRecord::Base
24
+ belongs_to :user
25
+ has_many :projects
26
+ has_one :public_profile
27
+ has_many :logs
28
+
29
+ prevent_destroy_if_any :user, :projects, :public_profile
30
+ end
31
+
32
+ Then in Rails you can write your PeopleController destroy action like this:
33
+
34
+ def destroy
35
+ person = Person.find params[:id]
36
+ if person.destroy
37
+ redirect_to people_url, :notice => "Person successfully deleted"
38
+ else
39
+ redirect_to person, :alert => person.errors.full_messages.join
40
+ end
41
+ end
42
+
43
+ License
44
+ ---
45
+
46
+ Copyright © 2011 Florent Guilleux, released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new :spec
5
+
6
+ task :default => :spec
@@ -0,0 +1,3 @@
1
+ module PreventDestroyIfAny
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ require "prevent_destroy_if_any/version"
2
+
3
+ class ActiveRecord::Base
4
+ def self.prevent_destroy_if_any(*association_names)
5
+ before_destroy do |model|
6
+ associations_present = []
7
+
8
+ association_names.each do |association_name|
9
+ association = model.send association_name
10
+ if association.class == Array
11
+ associations_present << association_name if association.any?
12
+ else
13
+ associations_present << association_name if association
14
+ end
15
+ end
16
+
17
+ if associations_present.any?
18
+ errors.add :base, "Cannot delete #{model.class.model_name.human.downcase} while #{associations_present.join ', '} exist"
19
+ return false
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "prevent_destroy_if_any/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "prevent_destroy_if_any"
7
+ s.version = PreventDestroyIfAny::VERSION
8
+ s.authors = ["Florent Guilleux"]
9
+ s.email = ["florent2@gmail.com"]
10
+ s.homepage = "https://github.com/Florent2/prevent_destroy_if_any"
11
+ s.summary = %q{ActiveRecord plugin to prevent destroy when associations are present}
12
+ s.description = %q{ActiveRecord plugin to prevent destroy when associations are present}
13
+
14
+ s.rubyforge_project = "prevent_destroy_if_any"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency "activerecord", '>= 3.0.0'
22
+ s.add_development_dependency "bundler", '>= 1.0.0'
23
+ s.add_development_dependency "rspec", '>= 0'
24
+ s.add_development_dependency "database_cleaner", '>= 0'
25
+ s.add_development_dependency "sqlite3-ruby", '>= 0'
26
+ s.add_development_dependency "rake", '>= 0'
27
+ end
@@ -0,0 +1,50 @@
1
+ require "spec_helper"
2
+
3
+ describe "prevent_destroy_if_any" do
4
+
5
+ let(:person) { Person.create! }
6
+
7
+ context "when there are associated records" do
8
+
9
+ it "destroy preventing works for has_many association" do
10
+ person.projects.create
11
+ person.destroy
12
+ person.destroyed?.should be_false
13
+ end
14
+
15
+ it "destroy preventing works for has_one association" do
16
+ person.create_public_profile
17
+ person.destroy
18
+ person.destroyed?.should be_false
19
+ end
20
+
21
+ it "destroy preventing works for belongs_ association" do
22
+ person.create_user
23
+ person.destroy
24
+ person.destroyed?.should be_false
25
+ end
26
+
27
+ it "adds an error message" do
28
+ person.projects.create
29
+ person.create_public_profile
30
+ person.destroy
31
+ person.errors[:base].first.should == "Cannot delete person while projects, public_profile exist"
32
+ end
33
+
34
+
35
+ it "does not prevent the destroy if the association is not listed as preventing the destroy" do
36
+ person.logs.create
37
+ person.destroy
38
+ person.destroyed?.should be_true
39
+ end
40
+ end
41
+
42
+ context "when there is no associated records" do
43
+
44
+ it "does not prevent the destroy" do
45
+ person.destroy
46
+ person.destroyed?.should be_true
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,60 @@
1
+ $:.unshift File.expand_path('..', __FILE__)
2
+ $:.unshift File.expand_path('../../lib', __FILE__)
3
+
4
+ require "rubygems"
5
+ require "bundler"
6
+ require "rspec"
7
+ require "active_record"
8
+ require "database_cleaner"
9
+
10
+ require "prevent_destroy_if_any"
11
+
12
+ ActiveRecord::Base.configurations = { 'test' => { :adapter => 'sqlite3', :database => ':memory:' } }
13
+ ActiveRecord::Base.establish_connection('test')
14
+
15
+ class Person < ActiveRecord::Base
16
+ belongs_to :user
17
+ has_many :projects
18
+ has_one :public_profile
19
+ has_many :logs
20
+
21
+ prevent_destroy_if_any :user, :projects, :public_profile
22
+ end
23
+
24
+ class User < ActiveRecord::Base
25
+ has_one :person
26
+ end
27
+
28
+ class Project < ActiveRecord::Base
29
+ belongs_to :person
30
+ end
31
+
32
+ class PublicProfile < ActiveRecord::Base
33
+ belongs_to :person
34
+ end
35
+
36
+ class Log < ActiveRecord::Base
37
+ belongs_to :person
38
+ end
39
+
40
+ ActiveRecord::Base.silence do
41
+ ActiveRecord::Migration.verbose = false
42
+ ActiveRecord::Schema.define :version => 0 do
43
+ create_table(:people) { |t| t.string :name; t.integer :user_id }
44
+ create_table(:users) { |t| t.string :uid }
45
+ create_table(:projects) { |t| t.string :name; t.integer :person_id }
46
+ create_table(:public_profiles) { |t| t.string :name; t.integer :person_id }
47
+ create_table(:logs) { |t| t.string :message; t.integer :person_id }
48
+ end
49
+ end
50
+
51
+ RSpec.configure do |config|
52
+ config.before(:suite) do
53
+ DatabaseCleaner.strategy = :truncation
54
+ DatabaseCleaner.clean
55
+ end
56
+
57
+ config.after(:each) do
58
+ DatabaseCleaner.clean
59
+ end
60
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prevent_destroy_if_any
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Florent Guilleux
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-07 00:00:00.000000000 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ requirement: &2157972440 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 3.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2157972440
26
+ - !ruby/object:Gem::Dependency
27
+ name: bundler
28
+ requirement: &2157971360 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *2157971360
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ requirement: &2157970640 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *2157970640
48
+ - !ruby/object:Gem::Dependency
49
+ name: database_cleaner
50
+ requirement: &2157969820 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *2157969820
59
+ - !ruby/object:Gem::Dependency
60
+ name: sqlite3-ruby
61
+ requirement: &2157968200 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *2157968200
70
+ - !ruby/object:Gem::Dependency
71
+ name: rake
72
+ requirement: &2157709680 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *2157709680
81
+ description: ActiveRecord plugin to prevent destroy when associations are present
82
+ email:
83
+ - florent2@gmail.com
84
+ executables: []
85
+ extensions: []
86
+ extra_rdoc_files: []
87
+ files:
88
+ - .gitignore
89
+ - Gemfile
90
+ - README.md
91
+ - Rakefile
92
+ - lib/prevent_destroy_if_any.rb
93
+ - lib/prevent_destroy_if_any/version.rb
94
+ - prevent_destroy_if_any.gemspec
95
+ - spec/prevent_destroy_if_any_spec.rb
96
+ - spec/spec_helper.rb
97
+ has_rdoc: true
98
+ homepage: https://github.com/Florent2/prevent_destroy_if_any
99
+ licenses: []
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ segments:
111
+ - 0
112
+ hash: 3762508194909461440
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ segments:
120
+ - 0
121
+ hash: 3762508194909461440
122
+ requirements: []
123
+ rubyforge_project: prevent_destroy_if_any
124
+ rubygems_version: 1.6.2
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: ActiveRecord plugin to prevent destroy when associations are present
128
+ test_files:
129
+ - spec/prevent_destroy_if_any_spec.rb
130
+ - spec/spec_helper.rb