aspgems-foreign_key_migrations 2.0.0.beta1 → 2.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +6 -0
- data/CHANGELOG +24 -0
- data/README.md +35 -4
- data/Rakefile +24 -18
- data/foreign_key_migrations.gemspec +1 -1
- data/lib/foreign_key_migrations.rb +5 -0
- data/lib/foreign_key_migrations/active_record/connection_adapters/table_definition.rb +11 -9
- data/lib/foreign_key_migrations/active_record/migration.rb +7 -3
- data/lib/foreign_key_migrations/version.rb +1 -1
- data/spec/connections/mysql/connection.rb +6 -6
- data/spec/connections/mysql2/connection.rb +6 -6
- data/spec/connections/postgresql/connection.rb +6 -3
- data/spec/migration_spec.rb +59 -20
- metadata +5 -4
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/CHANGELOG
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
2.0.0.beta2
|
2
|
+
* allow to disable automatic FK creation
|
3
|
+
1.2.0
|
4
|
+
* added install generator
|
5
|
+
* fixed doubled auto-index inside Schema.define
|
6
|
+
* upgraded to RSpec 2
|
7
|
+
* got rid of jeweler in favor of bundler
|
8
|
+
1.1.8
|
9
|
+
* depend on redhillonrails_core 1.1.2
|
10
|
+
1.1.7
|
11
|
+
* handle references for change_column
|
12
|
+
1.1
|
13
|
+
* create index within foreign key (auto index)
|
14
|
+
* global configuration for: auto_index and on_update/on_delete actions
|
15
|
+
1.0.2
|
16
|
+
* rails 3 generator
|
17
|
+
1.0.1
|
18
|
+
* used autoload
|
19
|
+
* rails 3 compatibility
|
20
|
+
1.0.0
|
21
|
+
* renamed from foreign_key_migration to automatic_foreign_key
|
22
|
+
* added gemspec
|
23
|
+
|
24
|
+
|
1
25
|
[REVISION 20080131]
|
2
26
|
|
3
27
|
[FIXED] Stack-level too deep.
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
[![Build Status](https://secure.travis-ci.org/aspgems/foreign_key_migrations.png)](http://travis-ci.org/aspgems/foreign_key_migrations)
|
2
|
+
|
3
|
+
Foreign Key Migrations
|
4
|
+
======================
|
2
5
|
|
3
6
|
Foreign Key Migrations is a plugin that automatically generates foreign-key
|
4
7
|
constraints when creating tables. It uses SQL-92 syntax and as such should be
|
@@ -8,51 +11,63 @@ In the simplest case, the plugin assumes that if you have a column named
|
|
8
11
|
<tt>customer_id</tt> that you want a foreign-key constraint generated that references
|
9
12
|
the <tt>id</tt> column in the <tt>customers</tt> table:
|
10
13
|
|
14
|
+
```ruby
|
11
15
|
create_table :orders do |t|
|
12
16
|
t.column :customer_id, :integer, :null => false
|
13
17
|
...
|
14
18
|
end
|
19
|
+
```
|
15
20
|
|
16
21
|
If you have multiple columns referencing a table or for whatever reason, your
|
17
22
|
column name isn't the same as the referenced table name, you can use the
|
18
23
|
`:references` option:
|
19
24
|
|
25
|
+
```ruby
|
20
26
|
create_table :orders do |t|
|
21
27
|
t.column :ordered_by_id, :integer, :null => false, :references => :customers
|
22
28
|
...
|
23
29
|
end
|
30
|
+
```
|
24
31
|
|
25
32
|
If you have a column with a name ending in <tt>_id</tt> for which you do not wish a
|
26
33
|
foreign-key to be generated, you can use `:references => nil`:
|
27
34
|
|
35
|
+
```ruby
|
28
36
|
create_table :orders do |t|
|
29
37
|
t.column :external_id, :integer, :null => false, :references => nil
|
30
38
|
...
|
31
39
|
end
|
40
|
+
```
|
32
41
|
|
33
42
|
Sometimes you may (for legacy reasons) need to reference a primary key column that is
|
34
43
|
named something other than <tt>id</tt>. In this case you can specify the name of the column:
|
35
44
|
|
45
|
+
```ruby
|
36
46
|
create_table :orders do |t|
|
37
47
|
t.column :ordered_by_pk, :integer, :null => false, :references => [:customers, :pk]
|
38
48
|
...
|
39
49
|
end
|
50
|
+
```
|
40
51
|
|
41
52
|
You also have the option of specifying what to do on delete/update using
|
42
53
|
`:on_delete`/`:on_update`, respectively to one of:
|
43
54
|
`:cascade`; `:restrict`; and `:set_null`:
|
44
55
|
|
56
|
+
```ruby
|
45
57
|
create_table :orders do |t|
|
46
58
|
t.column :customer_id, :integer, :on_delete => :set_null, :on_update => :cascade
|
47
59
|
...
|
48
60
|
end
|
61
|
+
```
|
49
62
|
|
50
63
|
If your database supports it (for example PostgreSQL) you can also mark the constraint as deferrable:
|
51
64
|
|
65
|
+
```ruby
|
52
66
|
create_table :orders do |t|
|
53
67
|
t.column :customer_id, :integer, :deferrable => true
|
54
68
|
...
|
55
69
|
end
|
70
|
+
```
|
56
71
|
|
57
72
|
By convention, if a column is named <tt>parent_id</tt> it will be treated as a circular reference to
|
58
73
|
the table in which it is defined.
|
@@ -61,10 +76,12 @@ Sometimes you may (for legacy reasons) need to name your primary key column such
|
|
61
76
|
would be misinterpreted as a foreign-key (say for example if you named the primary key
|
62
77
|
<tt>order_id</tt>). In this case you can manually create the primary key as follows:
|
63
78
|
|
79
|
+
```ruby
|
64
80
|
create_table :orders, :id => false do |t|
|
65
81
|
...
|
66
82
|
t.primary_key :order_id, :references => nil
|
67
83
|
end
|
84
|
+
```
|
68
85
|
|
69
86
|
There is also a generator for creating foreign keys on a database that currently has none:
|
70
87
|
|
@@ -77,15 +94,29 @@ configuration properties:
|
|
77
94
|
* `config.active_record.table_name_prefix`
|
78
95
|
* `config.active_record.table_name_suffix`
|
79
96
|
|
80
|
-
|
97
|
+
Install
|
98
|
+
-------
|
99
|
+
|
100
|
+
Put this line in your Gemfile:
|
101
|
+
|
102
|
+
gem 'aspgems-foreign_key_migrations', '~> 2.0.0.beta1', :require => 'foreign_key_migrations'
|
103
|
+
|
104
|
+
Then bundle:
|
105
|
+
|
106
|
+
% bundle
|
107
|
+
|
108
|
+
Dependencies
|
109
|
+
------------
|
81
110
|
|
82
111
|
* RedHill on Rails Core (redhillonrails_core) aspgems version.
|
83
112
|
|
84
|
-
|
113
|
+
NOTE
|
114
|
+
----
|
85
115
|
|
86
116
|
* Code was created by harukizaemon(http://github.com/harukizaemon) but is not supported currently by him.
|
87
117
|
|
88
|
-
|
118
|
+
License
|
119
|
+
-------
|
89
120
|
|
90
121
|
This plugin is copyright 2006 by RedHill Consulting, Pty. Ltd. and is released
|
91
122
|
under the MIT license.
|
data/Rakefile
CHANGED
@@ -10,34 +10,33 @@ require 'rspec/core/rake_task'
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
task :default => [:create_databases, :spec]
|
14
|
+
|
13
15
|
desc 'Run postgresql and mysql tests'
|
14
|
-
task :spec do
|
15
|
-
%w[postgresql mysql mysql2].each do |adapter|
|
16
|
+
task :spec do
|
17
|
+
%w[postgresql mysql mysql2 sqlite3].each do |adapter|
|
18
|
+
puts "\n\e[1;33m[#{ENV["BUNDLE_GEMFILE"]}] #{adapter}\e[m\n"
|
16
19
|
Rake::Task["#{adapter}:spec"].invoke
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
Rake::
|
24
|
-
|
25
|
-
|
26
|
-
rdoc.rdoc_dir = 'rdoc'
|
27
|
-
rdoc.title = "foreign key migrations #{version}"
|
28
|
-
rdoc.rdoc_files.include('README*')
|
29
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
|
+
desc 'Create databases'
|
24
|
+
task :create_databases do
|
25
|
+
%w[postgresql mysql].each do |adapter|
|
26
|
+
Rake::Task["#{adapter}:build_databases"].invoke
|
27
|
+
end
|
30
28
|
end
|
31
29
|
|
32
30
|
namespace :postgresql do
|
33
31
|
desc 'Build the PostgreSQL test databases'
|
34
32
|
task :build_databases do
|
35
|
-
|
33
|
+
system "psql -c 'create database foreign_key_migrations;' -U postgres >/dev/null"
|
34
|
+
abort "failed to create postgres database" unless $?.success?
|
36
35
|
end
|
37
36
|
|
38
37
|
desc 'Drop the PostgreSQL test databases'
|
39
38
|
task :drop_databases do
|
40
|
-
%x( dropdb
|
39
|
+
%x( dropdb foreign_key_migrations )
|
41
40
|
end
|
42
41
|
|
43
42
|
desc 'Rebuild the PostgreSQL test databases'
|
@@ -48,16 +47,16 @@ task :build_postgresql_databases => 'postgresql:build_databases'
|
|
48
47
|
task :drop_postgresql_databases => 'postgresql:drop_databases'
|
49
48
|
task :rebuild_postgresql_databases => 'postgresql:rebuild_databases'
|
50
49
|
|
51
|
-
MYSQL_DB_USER = 'fkm'
|
52
50
|
namespace :mysql do
|
53
51
|
desc 'Build the MySQL test databases'
|
54
52
|
task :build_databases do
|
55
|
-
|
53
|
+
system "mysql -e 'create database foreign_key_migrations default character set utf8 default collate utf8_unicode_ci;' >/dev/null"
|
54
|
+
abort "failed to create mysql database" unless $?.success?
|
56
55
|
end
|
57
56
|
|
58
57
|
desc 'Drop the MySQL test databases'
|
59
58
|
task :drop_databases do
|
60
|
-
%x( mysqladmin
|
59
|
+
%x( mysqladmin -f drop foreign_key_migrations )
|
61
60
|
end
|
62
61
|
|
63
62
|
desc 'Rebuild the MySQL test databases'
|
@@ -66,4 +65,11 @@ end
|
|
66
65
|
|
67
66
|
task :build_mysql_databases => 'mysql:build_databases'
|
68
67
|
task :drop_mysql_databases => 'mysql:drop_databases'
|
69
|
-
task :rebuild_mysql_databases => 'mysql:rebuild_databases'
|
68
|
+
task :rebuild_mysql_databases => 'mysql:rebuild_databases'
|
69
|
+
|
70
|
+
desc 'clobber generated files'
|
71
|
+
task :clobber do
|
72
|
+
rm_rf "pkg"
|
73
|
+
rm_rf "tmp"
|
74
|
+
rm "Gemfile.lock" if File.exist?("Gemfile.lock")
|
75
|
+
end
|
@@ -18,7 +18,7 @@ constraints when creating tables or adding columns. It uses SQL-92 syntax and as
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_dependency("aspgems-redhillonrails_core", "~> 2.0.0.
|
21
|
+
s.add_dependency("aspgems-redhillonrails_core", "~> 2.0.0.beta4")
|
22
22
|
|
23
23
|
s.add_development_dependency("rspec", "~> 2.5.0")
|
24
24
|
s.add_development_dependency("pg")
|
@@ -27,6 +27,11 @@ module ForeignKeyMigrations
|
|
27
27
|
mattr_accessor :auto_index
|
28
28
|
@@auto_index = nil
|
29
29
|
|
30
|
+
# Disable automatic foreign key creation.
|
31
|
+
# Useful for disabling automatic foreign keys in development env
|
32
|
+
# but enabling in test and production.
|
33
|
+
mattr_accessor :disable
|
34
|
+
|
30
35
|
# FIXME Not used by now
|
31
36
|
def self.setup(&block)
|
32
37
|
yield self
|
@@ -17,16 +17,18 @@ module ForeignKeyMigrations::ActiveRecord::ConnectionAdapters
|
|
17
17
|
|
18
18
|
def column_with_foreign_key_migrations(name, type, options = {})
|
19
19
|
column_without_foreign_key_migrations(name, type, options)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
unless ForeignKeyMigrations.disable
|
21
|
+
references = ActiveRecord::Base.references(self.name, name, options)
|
22
|
+
if references
|
23
|
+
ForeignKeyMigrations.set_default_update_and_delete_actions!(options)
|
24
|
+
foreign_key(name, references.first, references.last, options)
|
25
|
+
if index = fkm_index_options(options)
|
26
|
+
# append [column_name, index_options] pair
|
27
|
+
self.indices << [name, ForeignKeyMigrations.options_for_index(index)]
|
28
|
+
end
|
29
|
+
elsif options[:index]
|
30
|
+
self.indices << [name, ForeignKeyMigrations.options_for_index(options[:index])]
|
27
31
|
end
|
28
|
-
elsif options[:index]
|
29
|
-
self.indices << [name, ForeignKeyMigrations.options_for_index(options[:index])]
|
30
32
|
end
|
31
33
|
self
|
32
34
|
end
|
@@ -29,13 +29,17 @@ module ForeignKeyMigrations::ActiveRecord
|
|
29
29
|
#
|
30
30
|
def add_column(table_name, column_name, type, options = {})
|
31
31
|
super
|
32
|
-
|
32
|
+
unless ForeignKeyMigrations.disable
|
33
|
+
handle_column_options(table_name, column_name, options)
|
34
|
+
end
|
33
35
|
end
|
34
36
|
|
35
37
|
def change_column(table_name, column_name, type, options = {})
|
36
38
|
super
|
37
|
-
|
38
|
-
|
39
|
+
unless ForeignKeyMigrations.disable
|
40
|
+
remove_foreign_key_if_exists(table_name, column_name)
|
41
|
+
handle_column_options(table_name, column_name, options)
|
42
|
+
end
|
39
43
|
end
|
40
44
|
|
41
45
|
protected
|
@@ -1,16 +1,16 @@
|
|
1
1
|
print "Using MySQL\n"
|
2
2
|
require 'logger'
|
3
3
|
|
4
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
5
|
+
|
4
6
|
ActiveRecord::Base.configurations = {
|
5
|
-
'
|
7
|
+
'mysql' => {
|
6
8
|
:adapter => 'mysql',
|
7
|
-
:database => '
|
8
|
-
:username => '
|
9
|
+
:database => 'foreign_key_migrations',
|
10
|
+
:username => (ENV["TRAVIS"] ? '' : 'redhillonrails'),
|
9
11
|
:encoding => 'utf8',
|
10
|
-
:socket => '/var/run/mysqld/mysqld.sock',
|
11
|
-
:min_messages => 'warning'
|
12
12
|
}
|
13
13
|
|
14
14
|
}
|
15
15
|
|
16
|
-
ActiveRecord::Base.establish_connection '
|
16
|
+
ActiveRecord::Base.establish_connection 'mysql'
|
@@ -1,16 +1,16 @@
|
|
1
1
|
print "Using MySQL2\n"
|
2
2
|
require 'logger'
|
3
3
|
|
4
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
5
|
+
|
4
6
|
ActiveRecord::Base.configurations = {
|
5
|
-
'
|
7
|
+
'mysql2' => {
|
6
8
|
:adapter => 'mysql2',
|
7
|
-
:database => '
|
8
|
-
:username => '
|
9
|
+
:database => 'foreign_key_migrations',
|
10
|
+
:username => (ENV["TRAVIS"] ? '' : 'redhillonrails'),
|
9
11
|
:encoding => 'utf8',
|
10
|
-
:socket => '/var/run/mysqld/mysqld.sock',
|
11
|
-
:min_messages => 'warning'
|
12
12
|
}
|
13
13
|
|
14
14
|
}
|
15
15
|
|
16
|
-
ActiveRecord::Base.establish_connection '
|
16
|
+
ActiveRecord::Base.establish_connection 'mysql2'
|
@@ -1,13 +1,16 @@
|
|
1
1
|
print "Using PostgreSQL\n"
|
2
2
|
require 'logger'
|
3
3
|
|
4
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
5
|
+
|
4
6
|
ActiveRecord::Base.configurations = {
|
5
|
-
'
|
7
|
+
'postgres' => {
|
6
8
|
:adapter => 'postgresql',
|
7
|
-
:database => '
|
9
|
+
:database => 'foreign_key_migrations',
|
10
|
+
:username => 'postgres',
|
8
11
|
:min_messages => 'warning'
|
9
12
|
}
|
10
13
|
|
11
14
|
}
|
12
15
|
|
13
|
-
ActiveRecord::Base.establish_connection '
|
16
|
+
ActiveRecord::Base.establish_connection 'postgres'
|
data/spec/migration_spec.rb
CHANGED
@@ -54,7 +54,7 @@ describe ActiveRecord::Migration do
|
|
54
54
|
:state => { :index => {:with => :city} } )
|
55
55
|
@model.should have_index.on([:state, :city])
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
it "should auto-index foreign keys only" do
|
59
59
|
ForeignKeyMigrations.auto_index = true
|
60
60
|
create_table(@model, :user_id => {},
|
@@ -182,17 +182,6 @@ describe ActiveRecord::Migration do
|
|
182
182
|
ForeignKeyMigrations.on_delete = nil
|
183
183
|
end
|
184
184
|
|
185
|
-
protected
|
186
|
-
def add_column(column_name, *args)
|
187
|
-
table = @model.table_name
|
188
|
-
ActiveRecord::Migration.suppress_messages do
|
189
|
-
ActiveRecord::Migration.add_column(table, column_name, *args)
|
190
|
-
@model.reset_column_information
|
191
|
-
yield if block_given?
|
192
|
-
ActiveRecord::Migration.remove_column(table, column_name)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
185
|
end
|
197
186
|
|
198
187
|
context "when column is changed" do
|
@@ -225,18 +214,40 @@ describe ActiveRecord::Migration do
|
|
225
214
|
end
|
226
215
|
|
227
216
|
end
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
217
|
+
|
218
|
+
context "when disabled" do
|
219
|
+
|
220
|
+
before do
|
221
|
+
@model = Post
|
222
|
+
end
|
223
|
+
|
224
|
+
around do |example|
|
225
|
+
disable(&example)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should not create foreign key for created table" do
|
229
|
+
create_table(@model, :user_id => {})
|
230
|
+
@model.should_not reference.on(:user_id)
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should not create foreign for added column" do
|
234
|
+
create_table(@model, {})
|
235
|
+
add_column(:user_id, :integer) do
|
236
|
+
@model.should_not reference.on(:user_id)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should not create foreign key for changed column" do
|
241
|
+
create_table(@model, :user_id => { :references => nil })
|
242
|
+
change_column(:user_id, :integer)
|
243
|
+
@model.should_not reference.on(:user_id)
|
235
244
|
end
|
245
|
+
|
236
246
|
end
|
237
247
|
|
238
248
|
end
|
239
|
-
|
249
|
+
|
250
|
+
protected
|
240
251
|
def foreign_key(model, column)
|
241
252
|
columns = Array(column).collect(&:to_s)
|
242
253
|
model.foreign_keys.detect { |fk| fk.table_name == model.table_name && fk.column_names == columns }
|
@@ -253,5 +264,33 @@ describe ActiveRecord::Migration do
|
|
253
264
|
end
|
254
265
|
end
|
255
266
|
|
267
|
+
def add_column(column_name, *args)
|
268
|
+
table = @model.table_name
|
269
|
+
ActiveRecord::Migration.suppress_messages do
|
270
|
+
ActiveRecord::Migration.add_column(table, column_name, *args)
|
271
|
+
@model.reset_column_information
|
272
|
+
yield if block_given?
|
273
|
+
ActiveRecord::Migration.remove_column(table, column_name)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def change_column(column_name, *args)
|
278
|
+
table = @model.table_name
|
279
|
+
ActiveRecord::Migration.suppress_messages do
|
280
|
+
ActiveRecord::Migration.change_column(table, column_name, *args)
|
281
|
+
@model.reset_column_information
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def disable(&block)
|
286
|
+
old_value = ForeignKeyMigrations.disable
|
287
|
+
ForeignKeyMigrations.disable = true
|
288
|
+
begin
|
289
|
+
yield
|
290
|
+
ensure
|
291
|
+
ForeignKeyMigrations.disable = old_value
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
256
295
|
end
|
257
296
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: aspgems-foreign_key_migrations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 2.0.0.
|
5
|
+
version: 2.0.0.beta2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- "Micha\xC5\x82 \xC5\x81omnicki"
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-
|
14
|
+
date: 2011-08-06 00:00:00 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: aspgems-redhillonrails_core
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
requirements:
|
22
22
|
- - ~>
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 2.0.0.
|
24
|
+
version: 2.0.0.beta4
|
25
25
|
type: :runtime
|
26
26
|
version_requirements: *id001
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -80,6 +80,7 @@ extra_rdoc_files: []
|
|
80
80
|
|
81
81
|
files:
|
82
82
|
- .gitignore
|
83
|
+
- .travis.yml
|
83
84
|
- CHANGELOG
|
84
85
|
- Gemfile
|
85
86
|
- MIT-LICENSE
|
@@ -136,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
137
|
requirements: []
|
137
138
|
|
138
139
|
rubyforge_project:
|
139
|
-
rubygems_version: 1.
|
140
|
+
rubygems_version: 1.8.5
|
140
141
|
signing_key:
|
141
142
|
specification_version: 3
|
142
143
|
summary: Automatically generate foreign-key constraints when creating tables
|