dwilkie-foreigner 0.5.3 → 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.
- data/README.textile +53 -67
- data/Rakefile +16 -0
- data/VERSION +1 -0
- data/install.rb +1 -0
- data/lib/foreigner.rb +8 -0
- data/lib/foreigner/connection_adapters/abstract/schema_definitions.rb +42 -13
- data/lib/foreigner/connection_adapters/sqlite3_adapter.rb +0 -57
- data/tasks/foreigner_tasks.rake +4 -0
- data/test/app_root/db/migrate/create_bears.rb +14 -0
- data/test/app_root/db/migrate/create_cows.rb +14 -0
- data/test/app_root/db/migrate/create_elephants.rb +14 -0
- data/test/app_root/db/migrate/create_farms.rb +12 -0
- data/test/app_root/db/migrate/create_goats.rb +13 -0
- data/test/app_root/db/migrate/create_pigs.rb +13 -0
- data/test/app_root/db/migrate/create_sheep.rb +14 -0
- data/test/app_root/db/migrate/create_tigers.rb +13 -0
- data/test/mysql_adapter_test.rb +77 -1
- data/test/sqlite3_adapter_test.rb +87 -0
- data/test/{helper.rb → test_helper.rb} +10 -2
- data/uninstall.rb +1 -0
- metadata +40 -21
- data/rails/init.rb +0 -10
data/README.textile
CHANGED
@@ -1,85 +1,66 @@
|
|
1
1
|
h1. dwilkie Foreigner
|
2
2
|
|
3
3
|
dwilkie-foreigner is a fork of "Matt Higgins Foreigner":http://github.com/matthuhiggins/foreigner/
|
4
|
-
which supports adding AND enforcing foreign key constraints on
|
4
|
+
which supports adding AND enforcing foreign key constraints on SQLite3 databases.
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
dwilkie-foreigner allows you to do the following in your migration files
|
6
|
+
It also allows you to do the following in your migration files (not supported by matt higgins foreigner)
|
9
7
|
<pre>
|
10
8
|
create_table :comments do |t|
|
11
|
-
t.references :
|
9
|
+
t.references :post, :foreign_key => true, :null => false
|
12
10
|
end
|
13
11
|
</pre>
|
14
|
-
Which will generate the following SQL:
|
15
|
-
<pre>
|
16
|
-
CREATE TABLE "comments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
17
|
-
"post_id" integer NOT NULL,
|
18
|
-
FOREIGN KEY ("post_id") REFERENCES "posts"(id));
|
19
|
-
</pre>
|
20
12
|
|
21
|
-
|
13
|
+
h2. Enforcing constraints in SQLite3
|
14
|
+
|
15
|
+
SQLite3 does not enforce database constraints out of the box
|
16
|
+
This provides you with the flexibility in choosing whether or not to enforce
|
17
|
+
constraints at the DB level or not.
|
18
|
+
|
19
|
+
In order to enforce your constraints:
|
20
|
+
Rails 3
|
22
21
|
<pre>
|
23
|
-
|
24
|
-
|
25
|
-
t.foreign_key :posts, :column => :article_id
|
26
|
-
end
|
22
|
+
rails dbconsole
|
23
|
+
.genfkey --exec
|
27
24
|
</pre>
|
28
|
-
|
25
|
+
|
26
|
+
Rails 2.3.x
|
29
27
|
<pre>
|
30
|
-
|
31
|
-
|
32
|
-
FOREIGN KEY ("article_id") REFERENCES "posts"(id));
|
28
|
+
script/dbconsole
|
29
|
+
.genfkey --exec
|
33
30
|
</pre>
|
34
31
|
|
35
|
-
|
32
|
+
While your in the db console run: <pre>.schema</pre> to see your constraints implemented as triggers
|
33
|
+
|
34
|
+
Now when you try and remove a model with an association in Rails with sqlite3 you will get a database exception!
|
35
|
+
|
36
|
+
h2. Some More Examples
|
37
|
+
|
38
|
+
To specify a different column name you can do the following:
|
36
39
|
<pre>
|
37
40
|
create_table :comments do |t|
|
38
|
-
t.
|
41
|
+
t.integer :article_id, :null => false
|
42
|
+
t.foreign_key :post, :column => :article_id
|
39
43
|
end
|
40
44
|
</pre>
|
41
|
-
|
42
|
-
|
43
|
-
CREATE TABLE "comments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
44
|
-
"post_id" integer NOT NULL,
|
45
|
-
FOREIGN KEY ("post_id") REFERENCES "posts"(id) ON DELETE CASCADE);
|
46
|
-
</pre>
|
47
|
-
Or:
|
45
|
+
|
46
|
+
To specify dependencies (nullify or delete) you can do the following:
|
48
47
|
<pre>
|
49
48
|
create_table :comments do |t|
|
50
|
-
t.references :
|
51
|
-
t.foreign_key :posts, :column => :article_id, :dependent => :nullify
|
49
|
+
t.references :post, :foreign_key => {:dependent => :delete}, :null => false
|
52
50
|
end
|
53
51
|
</pre>
|
54
|
-
Which generates:
|
55
|
-
<pre>
|
56
|
-
CREATE TABLE "comments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
57
|
-
"article_id" integer NOT NULL,
|
58
|
-
FOREIGN KEY ("article_id") REFERENCES "posts"(id) ON DELETE SET NULL);
|
59
|
-
</pre>
|
60
|
-
|
61
|
-
h2. Enforcing constraints
|
62
|
-
|
63
|
-
SQLite does not enforce database constraints out of the box
|
64
|
-
This provides you with the flexibility in choosing whether or not to enforce
|
65
|
-
constraints at the DB level or not.
|
66
|
-
|
67
|
-
In order to enforce your constraints:
|
68
|
-
<pre>
|
69
|
-
script/dbconsole
|
70
|
-
.genfkey --exec
|
71
|
-
</pre>
|
72
52
|
|
73
|
-
|
53
|
+
Here's another example using a different column name and the dependent option
|
74
54
|
<pre>
|
75
|
-
|
55
|
+
create_table :comments do |t|
|
56
|
+
t.integer :article_id, :null => false
|
57
|
+
t.foreign_key :post, :column => :h2. Some More Examplesarticle_id, :dependent => :nullify
|
58
|
+
end
|
76
59
|
</pre>
|
77
|
-
to see your constraints implemented as triggers
|
78
60
|
|
79
61
|
h2. schema.rb
|
80
62
|
|
81
|
-
All of the constrants are updated in schema.rb
|
82
|
-
when you run:
|
63
|
+
All of the constrants are updated in schema.rb when you either:
|
83
64
|
<pre>
|
84
65
|
rake db:migrate
|
85
66
|
rake db:schema:dump
|
@@ -89,8 +70,7 @@ take advantage of using <pre>rake db:schema:load</pre>
|
|
89
70
|
|
90
71
|
h2. Limitations
|
91
72
|
|
92
|
-
Since
|
93
|
-
you cannot use the following syntax:
|
73
|
+
Since SQLite3 does not have complete ALTER TABLE support you cannot use the following syntax when using an SQLite3 database:
|
94
74
|
<pre>
|
95
75
|
add_foreign_key
|
96
76
|
remove_foreign_key
|
@@ -100,20 +80,26 @@ Therefore you must add your foreign keys when you define your table,
|
|
100
80
|
which may involve editing existing migration files instead of generating new ones
|
101
81
|
|
102
82
|
h2. Installation
|
83
|
+
h3. Rails 3
|
84
|
+
Add the following to your Gemfile:
|
85
|
+
<pre>gem "dwilkie-foreigner", :require => "foreigner"</pre>
|
86
|
+
Then run
|
87
|
+
<pre>bundle install</pre>
|
103
88
|
|
89
|
+
h3. Rails 2.3.x
|
104
90
|
Add the following to environment.rb:
|
105
|
-
<pre>
|
106
|
-
|
107
|
-
</pre>
|
108
|
-
Then run
|
109
|
-
<pre>
|
110
|
-
sudo rake gems:install
|
111
|
-
</pre>
|
91
|
+
<pre>config.gem "dwilkie-foreigner", :lib => "foreigner"</pre>
|
92
|
+
Then run:
|
93
|
+
<pre>sudo rake gems:install</pre>
|
112
94
|
|
113
|
-
h2.
|
95
|
+
h2. Post Install
|
96
|
+
To enable foreign keys you also need to add a file which
|
97
|
+
includes the line <pre>Foreigner.enable</pre> in your config/initializers directory
|
98
|
+
You can call this file whatever you want e.g. foreigner.rb
|
114
99
|
|
115
|
-
|
116
|
-
|
100
|
+
h2. Testing
|
101
|
+
There are built in tests for Mysql and SQLite3
|
102
|
+
In order to run them you need to install "Plugin Test Helper":http://github.com/pluginaweek/plugin_test_helper
|
117
103
|
|
118
|
-
Copyright (c)
|
104
|
+
Copyright (c) 2010 David Wilkie, released under the MIT license
|
119
105
|
|
data/Rakefile
CHANGED
@@ -21,3 +21,19 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
21
21
|
rdoc.rdoc_files.include('README')
|
22
22
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
23
|
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
require 'jeweler'
|
27
|
+
Jeweler::Tasks.new do |gemspec|
|
28
|
+
gemspec.name = "dwilkie-foreigner"
|
29
|
+
gemspec.summary = "Foreign keys for Rails migrations with SQLite support"
|
30
|
+
gemspec.description = "Allows you to add foreign keys to your migrations and enforce them"
|
31
|
+
gemspec.email = "dwilkie@gmail.com"
|
32
|
+
gemspec.homepage = "http://github.com/dwilkie/foreigner"
|
33
|
+
gemspec.authors = ["David Wilkie"]
|
34
|
+
end
|
35
|
+
Jeweler::GemcutterTasks.new
|
36
|
+
rescue LoadError
|
37
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
38
|
+
end
|
39
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Install hook code here
|
data/lib/foreigner.rb
CHANGED
@@ -17,6 +17,10 @@ module Foreigner
|
|
17
17
|
require adapters[adapter_name]
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
def enable
|
22
|
+
Foreigner.load_adapter! ActiveRecord::Base.connection_pool.spec.config[:adapter].downcase
|
23
|
+
end
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
@@ -31,3 +35,7 @@ module ActiveRecord
|
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
38
|
+
Foreigner.register 'mysql', 'foreigner/connection_adapters/mysql_adapter'
|
39
|
+
Foreigner.register 'postgresql', 'foreigner/connection_adapters/postgresql_adapter'
|
40
|
+
Foreigner.register 'sqlite3', 'foreigner/connection_adapters/sqlite3_adapter'
|
41
|
+
|
@@ -16,6 +16,14 @@ module Foreigner
|
|
16
16
|
end
|
17
17
|
|
18
18
|
module TableDefinition
|
19
|
+
class ForeignKey < Struct.new(:base, :to_table, :options)
|
20
|
+
|
21
|
+
def to_sql
|
22
|
+
base.foreign_key_definition(to_table, options)
|
23
|
+
end
|
24
|
+
alias to_s :to_sql
|
25
|
+
end
|
26
|
+
|
19
27
|
def self.included(base)
|
20
28
|
base.class_eval do
|
21
29
|
include InstanceMethods
|
@@ -25,23 +33,44 @@ module Foreigner
|
|
25
33
|
end
|
26
34
|
|
27
35
|
module InstanceMethods
|
36
|
+
# Adds a :foreign_key option to TableDefinition.references.
|
37
|
+
# If :foreign_key is true, a foreign key constraint is added to the table.
|
38
|
+
# You can also specify a hash, which is passed as foreign key options.
|
39
|
+
#
|
40
|
+
# ===== Examples
|
41
|
+
# ====== Add goat_id column and a foreign key to the goats table.
|
42
|
+
# t.references(:goat, :foreign_key => true)
|
43
|
+
# ====== Add goat_id column and a cascading foreign key to the goats table.
|
44
|
+
# t.references(:goat, :foreign_key => {:dependent => :delete})
|
45
|
+
#
|
46
|
+
# Note: No foreign key is created if :polymorphic => true is used.
|
28
47
|
def references_with_foreign_keys(*args)
|
29
48
|
options = args.extract_options!
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
)
|
49
|
+
fk_options = options.delete(:foreign_key)
|
50
|
+
|
51
|
+
if fk_options && !options[:polymorphic]
|
52
|
+
fk_options = {} if fk_options == true
|
53
|
+
args.each { |to_table| foreign_key(to_table, fk_options) }
|
35
54
|
end
|
36
55
|
|
37
56
|
references_without_foreign_keys(*(args << options))
|
38
57
|
end
|
39
58
|
|
59
|
+
# Defines a foreign key for the table. +to_table+ can be a single Symbol, or
|
60
|
+
# an Array of Symbols.
|
61
|
+
#
|
62
|
+
# ===== Examples
|
63
|
+
# ====== Creating a simple foreign key
|
64
|
+
# t.foreign_key(:person)
|
65
|
+
# ====== Defining the column
|
66
|
+
# t.foreign_key(:person, :column => :sender_id)
|
67
|
+
# ====== Specify cascading foreign key
|
68
|
+
# t.foreign_key(:person, :dependent => :delete)
|
40
69
|
def foreign_key(to_table, options = {})
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
70
|
+
if @base.supports_foreign_keys?
|
71
|
+
to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
|
72
|
+
foreign_keys << ForeignKey.new(@base, to_table, options)
|
73
|
+
end
|
45
74
|
end
|
46
75
|
|
47
76
|
def to_sql_with_foreign_keys
|
@@ -71,13 +100,13 @@ module Foreigner
|
|
71
100
|
#
|
72
101
|
# ===== Examples
|
73
102
|
# ====== Creating a simple foreign key
|
74
|
-
# t.foreign_key(:
|
103
|
+
# t.foreign_key(:person)
|
75
104
|
# ====== Defining the column
|
76
|
-
# t.foreign_key(:
|
105
|
+
# t.foreign_key(:person, :column => :sender_id)
|
77
106
|
# ====== Creating a named foreign key
|
78
|
-
# t.foreign_key(:
|
107
|
+
# t.foreign_key(:person, :column => :sender_id, :name => 'sender_foreign_key')
|
79
108
|
# ====== Defining the column of the +to_table+.
|
80
|
-
# t.foreign_key(:
|
109
|
+
# t.foreign_key(:person, :column => :sender_id, :primary_key => :person_id)
|
81
110
|
def foreign_key(to_table, options = {})
|
82
111
|
@base.add_foreign_key(@table_name, to_table, options)
|
83
112
|
end
|
@@ -33,63 +33,6 @@ AND name = '#{table_name}'
|
|
33
33
|
foreign_keys
|
34
34
|
end
|
35
35
|
end
|
36
|
-
module TableDefinition
|
37
|
-
class ForeignKey < Struct.new(:base, :to_table, :options)
|
38
|
-
|
39
|
-
def to_sql
|
40
|
-
base.foreign_key_definition(to_table, options)
|
41
|
-
end
|
42
|
-
alias to_s :to_sql
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.included(base)
|
46
|
-
base.class_eval do
|
47
|
-
include InstanceMethods
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
module InstanceMethods
|
52
|
-
# Adds a :foreign_key option to TableDefinition.references.
|
53
|
-
# If :foreign_key is true, a foreign key constraint is added to the table.
|
54
|
-
# You can also specify a hash, which is passed as foreign key options.
|
55
|
-
#
|
56
|
-
# ===== Examples
|
57
|
-
# ====== Add goat_id column and a foreign key to the goats table.
|
58
|
-
# t.references(:goat, :foreign_key => true)
|
59
|
-
# ====== Add goat_id column and a cascading foreign key to the goats table.
|
60
|
-
# t.references(:goat, :foreign_key => {:dependent => :delete})
|
61
|
-
#
|
62
|
-
# Note: No foreign key is created if :polymorphic => true is used.
|
63
|
-
def references_with_foreign_keys(*args)
|
64
|
-
options = args.extract_options!
|
65
|
-
fk_options = options.delete(:foreign_key)
|
66
|
-
|
67
|
-
if fk_options && !options[:polymorphic]
|
68
|
-
fk_options = {} if fk_options == true
|
69
|
-
args.each { |to_table| foreign_key(to_table, fk_options) }
|
70
|
-
end
|
71
|
-
|
72
|
-
references_without_foreign_keys(*(args << options))
|
73
|
-
end
|
74
|
-
|
75
|
-
# Defines a foreign key for the table. +to_table+ can be a single Symbol, or
|
76
|
-
# an Array of Symbols.
|
77
|
-
#
|
78
|
-
# ===== Examples
|
79
|
-
# ====== Creating a simple foreign key
|
80
|
-
# t.foreign_key(:people)
|
81
|
-
# ====== Defining the column
|
82
|
-
# t.foreign_key(:people, :column => :sender_id)
|
83
|
-
# ====== Specify cascading foreign key
|
84
|
-
# t.foreign_key(:people, :dependent => :delete)
|
85
|
-
def foreign_key(to_table, options = {})
|
86
|
-
if @base.supports_foreign_keys?
|
87
|
-
to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
|
88
|
-
foreign_keys << ForeignKey.new(@base, to_table, options)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
36
|
end
|
94
37
|
end
|
95
38
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateSheep < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :sheep do |t|
|
4
|
+
t.string :name
|
5
|
+
t.integer :shearing_farm_id
|
6
|
+
t.foreign_key :farm, :column => :shearing_farm_id
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
drop_table :sheep
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
data/test/mysql_adapter_test.rb
CHANGED
@@ -1,9 +1,65 @@
|
|
1
|
-
|
1
|
+
ENV['RAILS_ENV'] ||= 'mysql'
|
2
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
3
|
require "foreigner/connection_adapters/mysql_adapter"
|
3
4
|
|
4
5
|
class MysqlAdapterTest < ActiveRecord::TestCase
|
5
6
|
include Foreigner::ConnectionAdapters::MysqlAdapter
|
6
7
|
|
8
|
+
# t.foreign_key :farm
|
9
|
+
def test_adding_cows_to_the_farm_with_t_dot_foreign_key_farm
|
10
|
+
premigrate
|
11
|
+
table = "cows"
|
12
|
+
migrate table
|
13
|
+
assert_match(/FOREIGN KEY\s*\(\`farm_id\`\) REFERENCES \`farms\`\s*\(\`id\`\)/, schema(table))
|
14
|
+
end
|
15
|
+
|
16
|
+
# t.foreign_key :farm, :column => :shearing_farm_id
|
17
|
+
def test_adding_sheep_to_the_farm_with_t_dot_foreign_key_farm_column_id_shearing_farm_id
|
18
|
+
premigrate
|
19
|
+
table = "sheep"
|
20
|
+
migrate table
|
21
|
+
assert_match(/FOREIGN KEY\s*\(\`shearing_farm_id\`\) REFERENCES \`farms\`\s*\(\`id\`\)/, schema(table))
|
22
|
+
end
|
23
|
+
|
24
|
+
# t.foreign_key :farm, :dependent => :nullify
|
25
|
+
def test_adding_bears_to_the_farm_with_t_dot_foreign_key_farm_dependent_nullify
|
26
|
+
premigrate
|
27
|
+
table = "bears"
|
28
|
+
migrate table
|
29
|
+
assert_match(/FOREIGN KEY\s*\(\`farm_id\`\) REFERENCES \`farms\`\s*\(\`id\`\) ON DELETE SET NULL/, schema(table))
|
30
|
+
end
|
31
|
+
|
32
|
+
# t.foreign_key :farm, :dependent => :delete
|
33
|
+
def test_adding_elephants_to_the_farm_with_t_dot_foreign_key_farm_dependent_delete
|
34
|
+
premigrate
|
35
|
+
table = "elephants"
|
36
|
+
migrate table
|
37
|
+
assert_match(/FOREIGN KEY\s*\(\`farm_id\`\) REFERENCES \`farms\`\s*\(\`id\`\) ON DELETE CASCADE/, schema(table))
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_adding_pigs_to_the_farm_with_t_dot_references_farm_foreign_key_true
|
41
|
+
premigrate
|
42
|
+
table = "pigs"
|
43
|
+
migrate table
|
44
|
+
assert_match(/FOREIGN KEY\s*\(\`farm_id\`\) REFERENCES \`farms\`\s*\(\`id\`\)/, schema(table))
|
45
|
+
end
|
46
|
+
|
47
|
+
# t.references :farm, :foreign_key => {:dependent => :nullify}
|
48
|
+
def test_adding_tigers_to_the_farm_with_t_dot_references_farm_foreign_key_dependent_delete
|
49
|
+
premigrate
|
50
|
+
table = "tigers"
|
51
|
+
migrate table
|
52
|
+
assert_match(/FOREIGN KEY\s*\(\`farm_id\`\) REFERENCES \`farms\`\s*\(\`id\`\) ON DELETE SET NULL/, schema(table))
|
53
|
+
end
|
54
|
+
|
55
|
+
# t.references :farm, :foreign_key => {:dependent => :delete}
|
56
|
+
def test_adding_goats_to_the_farm_with_t_dot_references_farm_foreign_key_dependent_delete
|
57
|
+
premigrate
|
58
|
+
table = "goats"
|
59
|
+
migrate table
|
60
|
+
assert_match(/FOREIGN KEY\s*\(\`farm_id\`\) REFERENCES \`farms\`\s*\(\`id\`\) ON DELETE CASCADE/, schema(table))
|
61
|
+
end
|
62
|
+
|
7
63
|
def test_add_without_options
|
8
64
|
assert_equal(
|
9
65
|
"ALTER TABLE `employees` ADD CONSTRAINT `employees_company_id_fk` FOREIGN KEY (`company_id`) REFERENCES `companies`(id)",
|
@@ -81,5 +137,25 @@ class MysqlAdapterTest < ActiveRecord::TestCase
|
|
81
137
|
def quote_table_name(name)
|
82
138
|
quote_column_name(name).gsub('.', '`.`')
|
83
139
|
end
|
140
|
+
|
141
|
+
def premigrate
|
142
|
+
@database = ActiveRecord::Base.configurations['mysql']['database']
|
143
|
+
ActiveRecord::Base.connection.drop_database(@database)
|
144
|
+
ActiveRecord::Base.connection.create_database(@database)
|
145
|
+
ActiveRecord::Base.connection.reset!
|
146
|
+
migrate "farms"
|
147
|
+
end
|
148
|
+
|
149
|
+
def schema(table_name)
|
150
|
+
ActiveRecord::Base.connection.select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")["Create Table"]
|
151
|
+
end
|
152
|
+
|
153
|
+
def migrate(table_name)
|
154
|
+
migration = "create_#{table_name}"
|
155
|
+
require "app_root/db/migrate/#{migration}"
|
156
|
+
migration.camelcase.constantize.up
|
157
|
+
assert ActiveRecord::Base.connection.table_exists?(table_name)
|
158
|
+
end
|
159
|
+
|
84
160
|
end
|
85
161
|
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require "foreigner/connection_adapters/sqlite3_adapter"
|
3
|
+
|
4
|
+
require "ruby-debug"
|
5
|
+
|
6
|
+
class SQLite3AdapterTest < ActiveRecord::TestCase
|
7
|
+
|
8
|
+
# see the migration files under app_root/db/migrate for more details
|
9
|
+
|
10
|
+
# t.foreign_key :farm
|
11
|
+
def test_adding_cows_to_the_farm_with_t_dot_foreign_key_farm
|
12
|
+
premigrate
|
13
|
+
table = "cows"
|
14
|
+
migrate table
|
15
|
+
assert_match(/FOREIGN KEY \(\"farm_id\"\) REFERENCES \"farms\"\(id\)/, schema(table))
|
16
|
+
end
|
17
|
+
|
18
|
+
# t.foreign_key :farm, :column => :shearing_farm_id
|
19
|
+
def test_adding_sheep_to_the_farm_with_t_dot_foreign_key_farm_column_id_shearing_farm_id
|
20
|
+
premigrate
|
21
|
+
table = "sheep"
|
22
|
+
migrate table
|
23
|
+
assert_match(/FOREIGN KEY \(\"shearing_farm_id\"\) REFERENCES \"farms\"\(id\)/, schema(table))
|
24
|
+
end
|
25
|
+
|
26
|
+
# t.foreign_key :farm, :dependent => :nullify
|
27
|
+
def test_adding_bears_to_the_farm_with_t_dot_foreign_key_farm_dependent_nullify
|
28
|
+
premigrate
|
29
|
+
table = "bears"
|
30
|
+
migrate table
|
31
|
+
assert_match(/FOREIGN KEY \(\"farm_id\"\) REFERENCES \"farms\"\(id\) ON DELETE SET NULL/, schema(table))
|
32
|
+
end
|
33
|
+
|
34
|
+
# t.foreign_key :farm, :dependent => :delete
|
35
|
+
def test_adding_elephants_to_the_farm_with_t_dot_foreign_key_farm_dependent_delete
|
36
|
+
premigrate
|
37
|
+
table = "elephants"
|
38
|
+
migrate table
|
39
|
+
assert_match(/FOREIGN KEY \(\"farm_id\"\) REFERENCES \"farms\"\(id\) ON DELETE CASCADE/, schema(table))
|
40
|
+
end
|
41
|
+
|
42
|
+
# t.references :farm, :foreign_key => :true
|
43
|
+
def test_adding_pigs_to_the_farm_with_t_dot_references_farm_foreign_key_true
|
44
|
+
premigrate
|
45
|
+
table = "pigs"
|
46
|
+
migrate table
|
47
|
+
assert_match(/FOREIGN KEY \(\"farm_id\"\) REFERENCES \"farms\"\(id\)/, schema(table))
|
48
|
+
end
|
49
|
+
|
50
|
+
# t.references :farm, :foreign_key => {:dependent => :nullify}
|
51
|
+
def test_adding_tigers_to_the_farm_with_t_dot_references_farm_foreign_key_dependent_delete
|
52
|
+
premigrate
|
53
|
+
table = "tigers"
|
54
|
+
migrate table
|
55
|
+
assert_match(/FOREIGN KEY \(\"farm_id\"\) REFERENCES \"farms\"\(id\) ON DELETE SET NULL/, schema(table))
|
56
|
+
end
|
57
|
+
|
58
|
+
# t.references :farm, :foreign_key => {:dependent => :delete}
|
59
|
+
def test_adding_goats_to_the_farm_with_t_dot_references_farm_foreign_key_dependent_delete
|
60
|
+
premigrate
|
61
|
+
table = "goats"
|
62
|
+
migrate table
|
63
|
+
assert_match(/FOREIGN KEY \(\"farm_id\"\) REFERENCES \"farms\"\(id\) ON DELETE CASCADE/, schema(table))
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def premigrate
|
69
|
+
migrate "farms"
|
70
|
+
end
|
71
|
+
|
72
|
+
def schema(table_name)
|
73
|
+
ActiveRecord::Base.connection.select_value %{
|
74
|
+
SELECT sql
|
75
|
+
FROM sqlite_master
|
76
|
+
WHERE name = '#{table_name}'
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def migrate(table_name)
|
81
|
+
migration = "create_#{table_name}"
|
82
|
+
require "app_root/db/migrate/#{migration}"
|
83
|
+
migration.camelcase.constantize.up
|
84
|
+
assert ActiveRecord::Base.connection.table_exists?(table_name)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
@@ -1,6 +1,14 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# If you want to change the default rails environment
|
2
|
+
# ENV['RAILS_ENV'] ||= 'your_env'
|
3
|
+
|
4
|
+
# Load the plugin testing framework
|
3
5
|
require 'rubygems'
|
6
|
+
require 'plugin_test_helper'
|
7
|
+
|
8
|
+
# Run the migrations (optional)
|
9
|
+
# ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate")
|
10
|
+
|
11
|
+
require 'test/unit'
|
4
12
|
require 'active_support'
|
5
13
|
require 'active_support/test_case'
|
6
14
|
require 'active_record'
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Uninstall hook code here
|
metadata
CHANGED
@@ -3,10 +3,10 @@ name: dwilkie-foreigner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
|
+
- 1
|
6
7
|
- 0
|
7
|
-
-
|
8
|
-
|
9
|
-
version: 0.5.3
|
8
|
+
- 0
|
9
|
+
version: 1.0.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- David Wilkie
|
@@ -14,11 +14,11 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-27 00:00:00 +07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
21
|
-
description:
|
21
|
+
description: Allows you to add foreign keys to your migrations and enforce them
|
22
22
|
email: dwilkie@gmail.com
|
23
23
|
executables: []
|
24
24
|
|
@@ -28,28 +28,37 @@ extra_rdoc_files:
|
|
28
28
|
- README.textile
|
29
29
|
files:
|
30
30
|
- MIT-LICENSE
|
31
|
-
- Rakefile
|
32
31
|
- README.textile
|
33
|
-
-
|
32
|
+
- Rakefile
|
33
|
+
- VERSION
|
34
|
+
- install.rb
|
34
35
|
- lib/foreigner.rb
|
35
|
-
- lib/foreigner/
|
36
|
-
- lib/foreigner/connection_adapters/
|
36
|
+
- lib/foreigner/connection_adapters/abstract/schema_definitions.rb
|
37
|
+
- lib/foreigner/connection_adapters/abstract/schema_statements.rb
|
37
38
|
- lib/foreigner/connection_adapters/mysql_adapter.rb
|
38
39
|
- lib/foreigner/connection_adapters/postgresql_adapter.rb
|
40
|
+
- lib/foreigner/connection_adapters/sql_2003.rb
|
39
41
|
- lib/foreigner/connection_adapters/sqlite3_adapter.rb
|
40
|
-
- lib/foreigner/
|
41
|
-
-
|
42
|
-
- test/
|
42
|
+
- lib/foreigner/schema_dumper.rb
|
43
|
+
- tasks/foreigner_tasks.rake
|
44
|
+
- test/app_root/db/migrate/create_bears.rb
|
45
|
+
- test/app_root/db/migrate/create_cows.rb
|
46
|
+
- test/app_root/db/migrate/create_elephants.rb
|
47
|
+
- test/app_root/db/migrate/create_farms.rb
|
48
|
+
- test/app_root/db/migrate/create_goats.rb
|
49
|
+
- test/app_root/db/migrate/create_pigs.rb
|
50
|
+
- test/app_root/db/migrate/create_tigers.rb
|
43
51
|
- test/mysql_adapter_test.rb
|
52
|
+
- test/sqlite3_adapter_test.rb
|
53
|
+
- test/test_helper.rb
|
54
|
+
- uninstall.rb
|
44
55
|
has_rdoc: true
|
45
|
-
homepage: http://github.com/dwilkie/foreigner
|
56
|
+
homepage: http://github.com/dwilkie/foreigner
|
46
57
|
licenses: []
|
47
58
|
|
48
59
|
post_install_message:
|
49
60
|
rdoc_options:
|
50
|
-
- --
|
51
|
-
- --main
|
52
|
-
- README.textile
|
61
|
+
- --charset=UTF-8
|
53
62
|
require_paths:
|
54
63
|
- lib
|
55
64
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -68,10 +77,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
77
|
version: "0"
|
69
78
|
requirements: []
|
70
79
|
|
71
|
-
rubyforge_project:
|
80
|
+
rubyforge_project:
|
72
81
|
rubygems_version: 1.3.6
|
73
82
|
signing_key:
|
74
|
-
specification_version:
|
75
|
-
summary: Foreign keys for Rails migrations with
|
76
|
-
test_files:
|
77
|
-
|
83
|
+
specification_version: 3
|
84
|
+
summary: Foreign keys for Rails migrations with SQLite support
|
85
|
+
test_files:
|
86
|
+
- test/mysql_adapter_test.rb
|
87
|
+
- test/app_root/db/migrate/create_cows.rb
|
88
|
+
- test/app_root/db/migrate/create_goats.rb
|
89
|
+
- test/app_root/db/migrate/create_elephants.rb
|
90
|
+
- test/app_root/db/migrate/create_tigers.rb
|
91
|
+
- test/app_root/db/migrate/create_sheep.rb
|
92
|
+
- test/app_root/db/migrate/create_farms.rb
|
93
|
+
- test/app_root/db/migrate/create_bears.rb
|
94
|
+
- test/app_root/db/migrate/create_pigs.rb
|
95
|
+
- test/sqlite3_adapter_test.rb
|
96
|
+
- test/test_helper.rb
|
data/rails/init.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
require 'foreigner'
|
2
|
-
|
3
|
-
Foreigner.register 'mysql', 'foreigner/connection_adapters/mysql_adapter'
|
4
|
-
Foreigner.register 'postgresql', 'foreigner/connection_adapters/postgresql_adapter'
|
5
|
-
Foreigner.register 'sqlite3', 'foreigner/connection_adapters/sqlite3_adapter'
|
6
|
-
|
7
|
-
config.after_initialize do
|
8
|
-
Foreigner.load_adapter! ActiveRecord::Base.connection_pool.spec.config[:adapter].downcase
|
9
|
-
end
|
10
|
-
|