prevent_destroy_if_any 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/.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