aspgems-foreign_key_migrations 2.0.0.beta1 → 2.0.0.beta2
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 +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
|
+
[](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
|