active_record_foreign_keys 1.0.0

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.
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Anton Ageev
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,51 @@
1
+ = active_record_foreign_keys
2
+
3
+ Foreign keys support for ActiveRecord.
4
+
5
+ == Install
6
+
7
+ Rails::Initializer.run do |config|
8
+ ...
9
+ config.gem "active_record_foreign_keys", :source => "http://gemcutter.org"
10
+ ...
11
+ end
12
+
13
+ $ rake gems:install
14
+
15
+ == Usage
16
+
17
+ def self.up
18
+ # create reference table
19
+ create_table :users do |t|
20
+ end
21
+
22
+ # create referencing table
23
+ create_table :a_examples do |t|
24
+ t.references :user, :foreign_key => true
25
+ end
26
+
27
+ # or
28
+ create_table :b_examples do |t|
29
+ t.references :user, :foreign_key => { :on_update => :cascade, :on_delete => :restrict }
30
+ end
31
+
32
+ # or
33
+ create_table :c_examples do |t|
34
+ end
35
+
36
+ add_foreign_key :c_examples, :user_id, :users, :id, :on_update => :no_action, :on_delete => :set_null
37
+
38
+ # or change existing table
39
+ change_table :d_examples do |t|
40
+ t.references :user, :foreign_key => true
41
+ end
42
+ end
43
+
44
+ def self.down
45
+ # remove constraint
46
+ remove_foreign_key :examples, :user_id, :users, :id
47
+ end
48
+
49
+ == Copyright
50
+
51
+ Copyright (c) 2009 Anton Ageev. See LICENSE for details.
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "active_record_foreign_keys"
8
+ gem.summary = %Q{Foreign keys support for ActiveRecord}
9
+ gem.email = "antage@gmail.com"
10
+ gem.homepage = "http://github.com/antage/active_record_foreign_keys"
11
+ gem.authors = ["Anton Ageev"]
12
+ end
13
+ Jeweler::GemcutterTasks.new
14
+ rescue LoadError
15
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
16
+ end
17
+
18
+ require 'rake/testtask'
19
+ Rake::TestTask.new(:test) do |test|
20
+ test.libs << 'lib' << 'test'
21
+ test.pattern = 'test/**/*_test.rb'
22
+ test.verbose = true
23
+ end
24
+
25
+ begin
26
+ require 'rcov/rcovtask'
27
+ Rcov::RcovTask.new do |test|
28
+ test.libs << 'test'
29
+ test.pattern = 'test/**/*_test.rb'
30
+ test.verbose = true
31
+ end
32
+ rescue LoadError
33
+ task :rcov do
34
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
35
+ end
36
+ end
37
+
38
+ task :test => :check_dependencies
39
+
40
+ task :default => :test
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ if File.exist?('VERSION')
45
+ version = File.read('VERSION')
46
+ else
47
+ version = ""
48
+ end
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "active_record_foreign_keys #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,43 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{active_record_foreign_keys}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Anton Ageev"]
12
+ s.date = %q{2009-10-21}
13
+ s.email = %q{antage@gmail.com}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE",
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "LICENSE",
21
+ "README.rdoc",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "active_record_foreign_keys.gemspec",
25
+ "lib/active_record_foreign_keys.rb",
26
+ "rails/init.rb"
27
+ ]
28
+ s.homepage = %q{http://github.com/antage/active_record_foreign_keys}
29
+ s.rdoc_options = ["--charset=UTF-8"]
30
+ s.require_paths = ["lib"]
31
+ s.rubygems_version = %q{1.3.5}
32
+ s.summary = %q{Foreign keys support for ActiveRecord}
33
+
34
+ if s.respond_to? :specification_version then
35
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
36
+ s.specification_version = 3
37
+
38
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
39
+ else
40
+ end
41
+ else
42
+ end
43
+ end
@@ -0,0 +1,96 @@
1
+ require "active_record"
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ class TableDefinition
6
+ def references_with_foreign_key(*args)
7
+ options = args.extract_options!
8
+ cols = args.dup
9
+ fk_options = options.delete(:foreign_key) || false
10
+ references_without_foreign_key(*(args << options))
11
+ unless options[:polymorphic] || fk_options == false
12
+ @table_statements ||= []
13
+ fk_options = {} unless fk_options.is_a?(Hash)
14
+ cols.each do |col|
15
+ @table_statements << @base.foreign_key_sql(@table_name, "#{col}_id", col.to_s.pluralize, "id", fk_options)
16
+ end
17
+ end
18
+ end
19
+ alias_method_chain :references, :foreign_key
20
+
21
+ def to_sql_with_foreign_key
22
+ col_defs = to_sql_without_foreign_key
23
+ if @table_statements.is_a?(Array) && @table_statements.size > 0
24
+ sql = col_defs + ", " + (@table_statements * ", ")
25
+ else
26
+ sql = col_defs
27
+ end
28
+ sql
29
+ end
30
+ alias_method_chain :to_sql, :foreign_key
31
+ end
32
+
33
+ class Table
34
+ def references_with_foreign_key(*args)
35
+ options = args.extract_options!
36
+ cols = args.dup
37
+ fk_options = options.delete(:foreign_key) || false
38
+ references_without_foreign_key(*(args << options))
39
+ unless options[:polymorphic] || fk_options == false
40
+ fk_options = {} unless fk_options.is_a?(Hash)
41
+ cols.each { |col| @base.add_foreign_key(@table_name, "#{col}_id", col.to_s.pluralize, "id", fk_options) }
42
+ end
43
+ end
44
+ alias_method_chain :references, :foreign_key
45
+ end
46
+
47
+ module SchemaStatements
48
+ def add_foreign_key(table_name, column_name, reference_table_name, reference_column_name, options = {})
49
+ sql = <<-EOS
50
+ ALTER TABLE #{quote_table_name(table_name)}
51
+ ADD CONSTRAINT #{quote_table_name(foreign_key_constraint_name(table_name, column_name))}
52
+ EOS
53
+ sql += foreign_key_sql(table_name, column_name, reference_table_name, reference_column_name, options)
54
+ execute sql
55
+ end
56
+
57
+ def remove_foreign_key(table_name, column_name)
58
+ if foreign_key_exists?(table_name, column_name)
59
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP CONSTRAINT #{quote_table_name(foreign_key_constraint_name(table_name, column_name))}"
60
+ end
61
+ end
62
+
63
+ def foreign_key_sql(table_name, column_name, reference_table_name, reference_column_name, options = {})
64
+ options = {
65
+ :on_update => :no_action,
66
+ :on_delete => :no_action
67
+ }.merge(options)
68
+
69
+ "FOREIGN KEY (#{quote_column_name(column_name)}) REFERENCES #{quote_table_name(reference_table_name)}(#{quote_column_name(reference_column_name)}) ON UPDATE #{foreign_key_action(options[:on_update])} ON DELETE #{foreign_key_action(options[:on_delete])}"
70
+ end
71
+
72
+ private
73
+
74
+ def foreign_key_constraint_name(table_name, column_name)
75
+ "#{table_name}_#{column_name}_fkey"
76
+ end
77
+
78
+ def foreign_key_exists?(table_name, column_name)
79
+ count = select_value("SELECT COUNT(*) FROM pg_constraint WHERE conname = #{quote(foreign_key_constraint_name(table_name, column_name))}")
80
+ count.to_i > 0
81
+ end
82
+
83
+ def foreign_key_action(action)
84
+ case action
85
+ when :no_action then "NO ACTION"
86
+ when :restrict then "RESTRICT"
87
+ when :cascade then "CASCADE"
88
+ when :set_null then "SET NULL"
89
+ when :set_default then "SET DEFAULT"
90
+ else
91
+ raise ArgumentError, "Invalid action type. Valid actions are :on_update can be :no_action, :restrict, :cascade, :set_null, :set_default"
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1 @@
1
+ require "active_record_foreign_keys"
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_record_foreign_keys
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Anton Ageev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-21 00:00:00 +04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: antage@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .gitignore
27
+ - LICENSE
28
+ - README.rdoc
29
+ - Rakefile
30
+ - VERSION
31
+ - active_record_foreign_keys.gemspec
32
+ - lib/active_record_foreign_keys.rb
33
+ - rails/init.rb
34
+ has_rdoc: true
35
+ homepage: http://github.com/antage/active_record_foreign_keys
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --charset=UTF-8
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.3.5
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: Foreign keys support for ActiveRecord
62
+ test_files: []
63
+