immigrant 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/generators/immigration_generator.rb +1 -1
- data/lib/immigrant/compat/3.0.rb +6 -5
- data/lib/immigrant/compat/3.1.rb +6 -5
- data/lib/immigrant/compat/4.0.rb +14 -15
- data/lib/immigrant/compat/4.2.rb +12 -54
- data/lib/immigrant/compat/5.0.rb +1 -0
- data/lib/immigrant/compat/active_record.rb +44 -0
- data/lib/immigrant/compat/foreigner.rb +44 -0
- data/lib/immigrant/compat.rb +8 -52
- data/lib/immigrant/foreign_key_extensions.rb +23 -0
- data/lib/immigrant.rb +90 -32
- data/test/helper.rb +1 -0
- data/test/immigrant_test.rb +150 -128
- metadata +16 -18
- data/lib/immigrant/compat/foreigner_extensions.rb +0 -5
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 083bc4d18b381bf62146a71c000495a4b108fed2
|
4
|
+
data.tar.gz: b096073f024d41aa6362c2d3db3a3014aa8016ba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e1fe3e50d541c96400fbb476bcac1ac9176aa51e19b8d7e373398307aa34c0cabbea3a9353f932dd47d39439558fb367418b82eae651cac1fe7368c0d7d35e79
|
7
|
+
data.tar.gz: ce45456a29ebf673ea5a6b987990c70c784387db86804555edebe16812322d31534ff877aae37c071419dae0b26ba6052db2a51b31b5ebd1652f4282b8cbb7a8
|
@@ -3,7 +3,7 @@ require 'rails/generators/active_record'
|
|
3
3
|
class ImmigrationGenerator < ActiveRecord::Generators::Base
|
4
4
|
def create_immigration_file
|
5
5
|
Rails.application.eager_load!
|
6
|
-
@keys, warnings = Immigrant.infer_keys
|
6
|
+
@keys, warnings = Immigrant::KeyFinder.new.infer_keys
|
7
7
|
warnings.values.each{ |warning| $stderr.puts "WARNING: #{warning}" }
|
8
8
|
@keys.each do |key|
|
9
9
|
next unless key.options[:dependent] == :delete
|
data/lib/immigrant/compat/3.0.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
|
2
|
-
ForeignKeyDefinition = ::Foreigner::ConnectionAdapters::ForeignKeyDefinition
|
1
|
+
require_relative 'foreigner'
|
3
2
|
|
3
|
+
module Immigrant
|
4
4
|
TEMPLATE = 'immigration-pre-3.1.rb.erb'
|
5
5
|
FOREIGN_KEY = :primary_key_name
|
6
|
-
ON_DELETE = :dependent
|
7
6
|
|
8
|
-
|
9
|
-
reflection
|
7
|
+
class KeyFinder
|
8
|
+
def qualified_reflection?(reflection, klass)
|
9
|
+
reflection.options[:conditions].present?
|
10
|
+
end
|
10
11
|
end
|
11
12
|
end
|
data/lib/immigrant/compat/3.1.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
|
2
|
-
ForeignKeyDefinition = ::Foreigner::ConnectionAdapters::ForeignKeyDefinition
|
1
|
+
require_relative 'foreigner'
|
3
2
|
|
3
|
+
module Immigrant
|
4
4
|
TEMPLATE = 'immigration.rb.erb'
|
5
5
|
FOREIGN_KEY = :foreign_key
|
6
|
-
ON_DELETE = :dependent
|
7
6
|
|
8
|
-
|
9
|
-
reflection
|
7
|
+
class KeyFinder
|
8
|
+
def qualified_reflection?(reflection, klass)
|
9
|
+
reflection.options[:conditions].present?
|
10
|
+
end
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
data/lib/immigrant/compat/4.0.rb
CHANGED
@@ -1,22 +1,21 @@
|
|
1
|
-
|
2
|
-
ForeignKeyDefinition = ::Foreigner::ConnectionAdapters::ForeignKeyDefinition
|
1
|
+
require_relative 'foreigner'
|
3
2
|
|
3
|
+
module Immigrant
|
4
4
|
TEMPLATE = 'immigration.rb.erb'
|
5
5
|
FOREIGN_KEY = :foreign_key
|
6
|
-
ON_DELETE = :dependent
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
class KeyFinder
|
8
|
+
def qualified_reflection?(reflection, klass)
|
9
|
+
scope = reflection.scope
|
10
|
+
if scope.nil?
|
11
|
+
false
|
12
|
+
else
|
13
|
+
klass.instance_exec(*([nil]*scope.arity), &scope).where_values.present?
|
14
|
+
end
|
15
|
+
rescue
|
16
|
+
# if there's an error evaluating the scope block or whatever, just
|
17
|
+
# err on the side of caution and assume there are conditions
|
18
|
+
true
|
16
19
|
end
|
17
|
-
rescue
|
18
|
-
# if there's an error evaluating the scope block or whatever, just
|
19
|
-
# err on the side of caution and assume there are conditions
|
20
|
-
true
|
21
20
|
end
|
22
21
|
end
|
data/lib/immigrant/compat/4.2.rb
CHANGED
@@ -1,60 +1,18 @@
|
|
1
|
-
|
1
|
+
require_relative 'active_record'
|
2
2
|
|
3
3
|
module Immigrant
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
scope = reflection.scope
|
12
|
-
if scope.nil?
|
13
|
-
false
|
14
|
-
elsif scope.respond_to?(:options)
|
15
|
-
scope.options[:where].present?
|
16
|
-
else
|
17
|
-
klass.instance_exec(*([nil]*scope.arity), &scope).where_values.present?
|
18
|
-
end
|
19
|
-
rescue
|
20
|
-
# if there's an error evaluating the scope block or whatever, just
|
21
|
-
# err on the side of caution and assume there are conditions
|
22
|
-
true
|
23
|
-
end
|
24
|
-
|
25
|
-
module ForeignKeyExtensions
|
26
|
-
# DRY alert: copied from ActiveRecord::SchemaDumper#foreign_keys
|
27
|
-
def dump_foreign_key(foreign_key)
|
28
|
-
parts = [
|
29
|
-
"add_foreign_key #{remove_prefix_and_suffix(foreign_key.from_table).inspect}",
|
30
|
-
remove_prefix_and_suffix(foreign_key.to_table).inspect,
|
31
|
-
]
|
32
|
-
|
33
|
-
if foreign_key.column != foreign_key_column_for(foreign_key.to_table)
|
34
|
-
parts << "column: #{foreign_key.column.inspect}"
|
35
|
-
end
|
36
|
-
|
37
|
-
if foreign_key.custom_primary_key?
|
38
|
-
parts << "primary_key: #{foreign_key.primary_key.inspect}"
|
4
|
+
class KeyFinder
|
5
|
+
def qualified_reflection?(reflection, klass)
|
6
|
+
scope = reflection.scope
|
7
|
+
if scope.nil?
|
8
|
+
false
|
9
|
+
else
|
10
|
+
klass.instance_exec(*([nil]*scope.arity), &scope).where_values.present?
|
39
11
|
end
|
40
|
-
|
41
|
-
if
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
parts << "on_update: #{foreign_key.on_update.inspect}" if foreign_key.on_update
|
46
|
-
parts << "on_delete: #{foreign_key.on_delete.inspect}" if foreign_key.on_delete
|
47
|
-
|
48
|
-
" #{parts.join(', ')}"
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
def remove_prefix_and_suffix(table)
|
53
|
-
table.gsub(/^(#{ActiveRecord::Base.table_name_prefix})(.+)(#{ActiveRecord::Base.table_name_suffix})$/, "\\2")
|
54
|
-
end
|
55
|
-
|
56
|
-
def foreign_key_column_for(table_name)
|
57
|
-
"#{table_name.to_s.singularize}_id"
|
12
|
+
rescue
|
13
|
+
# if there's an error evaluating the scope block or whatever, just
|
14
|
+
# err on the side of caution and assume there are conditions
|
15
|
+
true
|
58
16
|
end
|
59
17
|
end
|
60
18
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'active_record'
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "active_record/connection_adapters/abstract/schema_definitions"
|
2
|
+
|
3
|
+
module Immigrant
|
4
|
+
ForeignKeyDefinition = ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition
|
5
|
+
|
6
|
+
TEMPLATE = 'immigration.rb.erb'
|
7
|
+
FOREIGN_KEY = :foreign_key
|
8
|
+
|
9
|
+
module ForeignKeyExtensions
|
10
|
+
# DRY alert: copied from ActiveRecord::SchemaDumper#foreign_keys
|
11
|
+
def dump_foreign_key(foreign_key)
|
12
|
+
parts = [
|
13
|
+
"add_foreign_key #{remove_prefix_and_suffix(foreign_key.from_table).inspect}",
|
14
|
+
remove_prefix_and_suffix(foreign_key.to_table).inspect,
|
15
|
+
]
|
16
|
+
|
17
|
+
if foreign_key.column != foreign_key_column_for(foreign_key.to_table)
|
18
|
+
parts << "column: #{foreign_key.column.inspect}"
|
19
|
+
end
|
20
|
+
|
21
|
+
if foreign_key.custom_primary_key?
|
22
|
+
parts << "primary_key: #{foreign_key.primary_key.inspect}"
|
23
|
+
end
|
24
|
+
|
25
|
+
if foreign_key.name !~ /^fk_rails_[0-9a-f]{10}$/
|
26
|
+
parts << "name: #{foreign_key.name.inspect}"
|
27
|
+
end
|
28
|
+
|
29
|
+
parts << "on_update: #{foreign_key.on_update.inspect}" if foreign_key.on_update
|
30
|
+
parts << "on_delete: #{foreign_key.on_delete.inspect}" if foreign_key.on_delete
|
31
|
+
|
32
|
+
parts.join(', ')
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def remove_prefix_and_suffix(table)
|
37
|
+
table.gsub(/^(#{ActiveRecord::Base.table_name_prefix})(.+)(#{ActiveRecord::Base.table_name_suffix})$/, "\\2")
|
38
|
+
end
|
39
|
+
|
40
|
+
def foreign_key_column_for(table_name)
|
41
|
+
"#{table_name.to_s.singularize}_id"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
begin
|
2
|
+
require 'foreigner'
|
3
|
+
rescue LoadError
|
4
|
+
$stderr.puts <<-ERR.strip_heredoc
|
5
|
+
|
6
|
+
ERROR: immigrant requires the foreigner gem (unless you are on rails 4.2+)
|
7
|
+
|
8
|
+
To fix this, add the following to your Gemfile:
|
9
|
+
|
10
|
+
gem "foreigner", "~> 1.2"
|
11
|
+
|
12
|
+
Or just upgrade rails ;) ... lol, "just"
|
13
|
+
|
14
|
+
ERR
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
Foreigner.load
|
18
|
+
|
19
|
+
module Immigrant
|
20
|
+
ForeignKeyDefinition = ::Foreigner::ConnectionAdapters::ForeignKeyDefinition
|
21
|
+
|
22
|
+
module ForeignKeyExtensions
|
23
|
+
include Foreigner::SchemaDumper::ClassMethods
|
24
|
+
|
25
|
+
def self.included(klass)
|
26
|
+
# ForeignKeyExtensions already overrides initialize; override it
|
27
|
+
# some more
|
28
|
+
klass.send(:include, Module.new{
|
29
|
+
def initialize(from_table, to_table, options)
|
30
|
+
options.delete(:on_update)
|
31
|
+
options[:dependent] = normalize_dependent(options.delete(:on_delete))
|
32
|
+
super
|
33
|
+
end
|
34
|
+
})
|
35
|
+
end
|
36
|
+
|
37
|
+
def normalize_dependent(value)
|
38
|
+
case value
|
39
|
+
when :cascade then :delete
|
40
|
+
else value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/immigrant/compat.rb
CHANGED
@@ -1,57 +1,13 @@
|
|
1
1
|
version = ActiveRecord::VERSION::STRING
|
2
2
|
|
3
|
-
if version >= '
|
3
|
+
if version >= '5.0.'
|
4
|
+
require_relative 'compat/5.0'
|
5
|
+
elsif version >= '4.2.'
|
4
6
|
require_relative 'compat/4.2'
|
7
|
+
elsif version >= '4.0'
|
8
|
+
require_relative 'compat/4.0'
|
9
|
+
elsif version >= '3.1'
|
10
|
+
require_relative 'compat/3.1'
|
5
11
|
else
|
6
|
-
|
7
|
-
require 'foreigner'
|
8
|
-
rescue LoadError
|
9
|
-
$stderr.puts <<-ERR.strip_heredoc
|
10
|
-
|
11
|
-
ERROR: immigrant requires the foreigner gem (unless you are on rails 4.2+)
|
12
|
-
|
13
|
-
To fix this, add the following to your Gemfile:
|
14
|
-
|
15
|
-
gem "foreigner", "~> 1.2"
|
16
|
-
|
17
|
-
Or just upgrade rails ;) ... lol, "just"
|
18
|
-
|
19
|
-
ERR
|
20
|
-
exit 1
|
21
|
-
end
|
22
|
-
Foreigner.load
|
23
|
-
|
24
|
-
require_relative 'compat/foreigner_extensions'
|
25
|
-
|
26
|
-
if version >= '4.0'
|
27
|
-
require_relative 'compat/4.0'
|
28
|
-
elsif version >= '3.1'
|
29
|
-
require_relative 'compat/3.1'
|
30
|
-
else
|
31
|
-
require_relative 'compat/3.0'
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# add some useful things for querying/comparing/dumping foreign keys
|
36
|
-
module Immigrant
|
37
|
-
module ForeignKeyExtensions
|
38
|
-
def initialize(from_table, to_table, options, *args)
|
39
|
-
options ||= {}
|
40
|
-
options[:name] ||= "#{from_table}_#{options[:column]}_fk"
|
41
|
-
super(from_table, to_table, options, *args)
|
42
|
-
end
|
43
|
-
|
44
|
-
def hash_key
|
45
|
-
[from_table, options[:column]]
|
46
|
-
end
|
47
|
-
|
48
|
-
def to_ruby(action = :add)
|
49
|
-
if action == :add
|
50
|
-
dump_foreign_key(self)
|
51
|
-
else
|
52
|
-
"remove_foreign_key #{from_table.inspect}, " \
|
53
|
-
":name => #{options[:name].inspect}"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
12
|
+
require_relative 'compat/3.0'
|
57
13
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# add some useful things for querying/comparing/dumping foreign keys
|
2
|
+
module Immigrant
|
3
|
+
module ForeignKeyExtensions
|
4
|
+
def initialize(from_table, to_table, options, *args)
|
5
|
+
options ||= {}
|
6
|
+
options[:name] ||= "#{from_table}_#{options[:column]}_fk"
|
7
|
+
super(from_table, to_table, options, *args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def hash_key
|
11
|
+
[from_table, options[:column]]
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_ruby(action = :add)
|
15
|
+
if action == :add
|
16
|
+
dump_foreign_key(self)
|
17
|
+
else
|
18
|
+
"remove_foreign_key #{from_table.inspect}, " \
|
19
|
+
":name => #{options[:name].inspect}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/immigrant.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'active_support/all'
|
2
2
|
|
3
3
|
module Immigrant
|
4
|
-
class
|
4
|
+
class KeyFinder
|
5
5
|
def infer_keys(db_keys = current_foreign_keys, classes = model_classes)
|
6
6
|
database_keys = db_keys.inject({}) { |hash, foreign_key|
|
7
7
|
hash[foreign_key.hash_key] = foreign_key
|
@@ -27,8 +27,12 @@ module Immigrant
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
+
def tables
|
31
|
+
@tables ||= ActiveRecord::Base.connection.tables
|
32
|
+
end
|
33
|
+
|
30
34
|
def current_foreign_keys
|
31
|
-
|
35
|
+
tables.map{ |table|
|
32
36
|
ActiveRecord::Base.connection.foreign_keys(table)
|
33
37
|
}.flatten
|
34
38
|
end
|
@@ -81,16 +85,17 @@ module Immigrant
|
|
81
85
|
end
|
82
86
|
|
83
87
|
def foreign_keys_for(klass)
|
88
|
+
return [] if klass.abstract_class? || !tables.include?(klass.table_name)
|
84
89
|
candidate_reflections_for(klass).inject([]) do |result, reflection|
|
85
90
|
begin
|
86
|
-
result.concat
|
91
|
+
result.concat foreign_keys_for_reflection(klass, reflection)
|
87
92
|
rescue NameError # e.g. belongs_to :oops_this_is_not_a_table
|
88
93
|
result
|
89
94
|
end
|
90
95
|
end
|
91
96
|
end
|
92
97
|
|
93
|
-
def
|
98
|
+
def foreign_keys_for_reflection(klass, reflection)
|
94
99
|
case reflection.macro
|
95
100
|
when :belongs_to
|
96
101
|
infer_belongs_to_keys(klass, reflection)
|
@@ -98,59 +103,112 @@ module Immigrant
|
|
98
103
|
infer_has_n_keys(klass, reflection)
|
99
104
|
when :has_and_belongs_to_many
|
100
105
|
infer_habtm_keys(klass, reflection)
|
101
|
-
|
102
|
-
[]
|
103
|
-
end
|
106
|
+
end || []
|
104
107
|
end
|
105
108
|
|
106
109
|
def infer_belongs_to_keys(klass, reflection)
|
107
|
-
return
|
110
|
+
return if reflection.name == :left_side # redundant and unusable reflection automagically created by HABTM
|
111
|
+
|
112
|
+
from_table = klass.table_name
|
113
|
+
to_table = reflection.klass.table_name
|
114
|
+
column = reflection.send(FOREIGN_KEY).to_s
|
115
|
+
primary_key = (reflection.options[:primary_key] || reflection.klass.primary_key).to_s
|
116
|
+
|
117
|
+
return unless column_exists?(from_table, column)
|
118
|
+
|
108
119
|
[
|
109
120
|
ForeignKeyDefinition.new(
|
110
|
-
|
111
|
-
|
112
|
-
:column =>
|
113
|
-
:primary_key =>
|
121
|
+
from_table,
|
122
|
+
to_table,
|
123
|
+
:column => column,
|
124
|
+
:primary_key => primary_key
|
114
125
|
# although belongs_to can specify :dependent, it doesn't make
|
115
|
-
# sense from a foreign key perspective
|
116
|
-
ON_DELETE => nil
|
126
|
+
# sense from a foreign key perspective, so no :on_delete
|
117
127
|
)
|
118
128
|
]
|
119
129
|
end
|
120
130
|
|
121
131
|
def infer_has_n_keys(klass, reflection)
|
132
|
+
from_table = reflection.klass.table_name
|
133
|
+
to_table = klass.table_name
|
134
|
+
column = reflection.send(FOREIGN_KEY).to_s
|
135
|
+
primary_key = (reflection.options[:primary_key] || klass.primary_key).to_s
|
136
|
+
|
137
|
+
actions = {}
|
138
|
+
if [:delete, :delete_all].include?(reflection.options[:dependent]) && !qualified_reflection?(reflection, klass)
|
139
|
+
actions = {:on_delete => :cascade, :on_update => :cascade}
|
140
|
+
end
|
141
|
+
|
142
|
+
return unless column_exists?(from_table, column)
|
143
|
+
|
122
144
|
[
|
123
145
|
ForeignKeyDefinition.new(
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
146
|
+
from_table,
|
147
|
+
to_table,
|
148
|
+
{
|
149
|
+
:column => column,
|
150
|
+
:primary_key => primary_key
|
151
|
+
}.merge(actions)
|
129
152
|
)
|
130
153
|
]
|
131
154
|
end
|
132
155
|
|
133
156
|
def infer_habtm_keys(klass, reflection)
|
157
|
+
keys = []
|
158
|
+
|
134
159
|
join_table = (reflection.respond_to?(:join_table) ? reflection.join_table : reflection.options[:join_table]).to_s
|
135
|
-
|
136
|
-
|
160
|
+
|
161
|
+
left_to_table = klass.table_name
|
162
|
+
left_column = reflection.send(FOREIGN_KEY).to_s
|
163
|
+
left_primary_key = klass.primary_key.to_s
|
164
|
+
if column_exists?(join_table, left_column)
|
165
|
+
keys << ForeignKeyDefinition.new(
|
137
166
|
join_table,
|
138
|
-
|
139
|
-
:column =>
|
140
|
-
:primary_key =>
|
141
|
-
|
142
|
-
|
143
|
-
|
167
|
+
left_to_table,
|
168
|
+
:column => left_column,
|
169
|
+
:primary_key => left_primary_key
|
170
|
+
)
|
171
|
+
end
|
172
|
+
|
173
|
+
right_to_table = reflection.klass.table_name
|
174
|
+
right_column = reflection.association_foreign_key.to_s
|
175
|
+
right_primary_key = reflection.klass.primary_key.to_s
|
176
|
+
if column_exists?(join_table, left_column)
|
177
|
+
keys << ForeignKeyDefinition.new(
|
144
178
|
join_table,
|
145
|
-
|
146
|
-
:column =>
|
147
|
-
:primary_key =>
|
148
|
-
ON_DELETE => nil
|
179
|
+
right_to_table,
|
180
|
+
:column => right_column,
|
181
|
+
:primary_key => right_primary_key
|
149
182
|
)
|
150
|
-
|
183
|
+
end
|
184
|
+
|
185
|
+
keys
|
186
|
+
end
|
187
|
+
|
188
|
+
def column_exists?(table_name, column_name)
|
189
|
+
columns_for(table_name).any? { |column| column.name == column_name }
|
190
|
+
end
|
191
|
+
|
192
|
+
def columns_for(table_name)
|
193
|
+
@columns ||= {}
|
194
|
+
@columns[table_name] ||= ActiveRecord::Base.connection.columns(table_name)
|
195
|
+
end
|
196
|
+
|
197
|
+
def qualified_reflection?(reflection, klass)
|
198
|
+
scope = reflection.scope
|
199
|
+
if scope.nil?
|
200
|
+
false
|
201
|
+
else
|
202
|
+
klass.instance_exec(*([nil]*scope.arity), &scope).where_clause.any?
|
203
|
+
end
|
204
|
+
rescue
|
205
|
+
# if there's an error evaluating the scope block or whatever, just
|
206
|
+
# err on the side of caution and assume there are conditions
|
207
|
+
true
|
151
208
|
end
|
152
209
|
end
|
153
210
|
end
|
154
211
|
|
155
212
|
require 'immigrant/loader'
|
213
|
+
require 'immigrant/foreign_key_extensions'
|
156
214
|
require 'immigrant/railtie' if defined?(Rails)
|
data/test/helper.rb
CHANGED
data/test/immigrant_test.rb
CHANGED
@@ -3,22 +3,19 @@ require 'helper'
|
|
3
3
|
class ImmigrantTest < ActiveSupport::TestCase
|
4
4
|
include TestMethods
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def connection
|
13
|
-
@connection ||= MockConnection.new
|
14
|
-
end
|
6
|
+
ActiveRecord::Base.instance_eval do
|
7
|
+
def primary_key
|
8
|
+
connection.primary_key(table_name)
|
9
|
+
end
|
10
|
+
def connection
|
11
|
+
@connection ||= MockConnection.new
|
15
12
|
end
|
16
13
|
|
17
14
|
if ActiveRecord::VERSION::STRING >= '4.'
|
18
15
|
# support old 3.x syntax for the sake of concise tests
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
extend(Module.new{
|
17
|
+
[:belongs_to, :has_one, :has_many, :has_and_belongs_to_many].each do |method|
|
18
|
+
define_method method do |assoc, scope = nil, options = {}|
|
22
19
|
if scope.is_a?(Hash)
|
23
20
|
options = scope
|
24
21
|
scope_opts = options.extract!(:conditions, :order)
|
@@ -28,8 +25,8 @@ class ImmigrantTest < ActiveSupport::TestCase
|
|
28
25
|
end
|
29
26
|
super assoc, scope, options
|
30
27
|
end
|
31
|
-
|
32
|
-
|
28
|
+
end
|
29
|
+
})
|
33
30
|
end
|
34
31
|
end
|
35
32
|
|
@@ -40,18 +37,27 @@ class ImmigrantTest < ActiveSupport::TestCase
|
|
40
37
|
def primary_key(table)
|
41
38
|
table.to_s !~ /s_.*s\z/ ? 'id' : nil
|
42
39
|
end
|
40
|
+
def tables
|
41
|
+
ActiveSupport::DescendantsTracker.direct_descendants(ActiveRecord::Base).map(&:table_name)
|
42
|
+
end
|
43
|
+
def columns(table_name)
|
44
|
+
AnyColumn.new
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class AnyColumn
|
49
|
+
def any?
|
50
|
+
true
|
51
|
+
end
|
43
52
|
end
|
44
53
|
|
45
54
|
def teardown
|
46
|
-
subclasses = ActiveSupport::DescendantsTracker.direct_descendants(
|
55
|
+
subclasses = ActiveSupport::DescendantsTracker.direct_descendants(ActiveRecord::Base)
|
47
56
|
subclasses.each do |subclass|
|
48
|
-
|
57
|
+
subclass = subclass.to_s
|
58
|
+
Object.send(:remove_const, subclass) if subclass =~ /\A[A-Z]/ && Object.const_defined?(subclass)
|
49
59
|
end
|
50
60
|
subclasses.replace([])
|
51
|
-
# also need to clear out other things under AR::Base, because as of
|
52
|
-
# 4.1 there are automagical anonymous classes due to HABTM
|
53
|
-
subclasses = ActiveSupport::DescendantsTracker.direct_descendants(ActiveRecord::Base)
|
54
|
-
subclasses.replace([MockModel])
|
55
61
|
end
|
56
62
|
|
57
63
|
def given(code)
|
@@ -60,194 +66,183 @@ class ImmigrantTest < ActiveSupport::TestCase
|
|
60
66
|
Object.class_eval code
|
61
67
|
end
|
62
68
|
|
69
|
+
def infer_keys(db_keys = [])
|
70
|
+
keys = Immigrant::KeyFinder.new.infer_keys(db_keys).first
|
71
|
+
# ensure each key generates correctly
|
72
|
+
keys.each { |key| key.to_ruby(:add) }
|
73
|
+
keys.sort_by { |key| [key.from_table, key.to_table] }
|
74
|
+
end
|
75
|
+
|
63
76
|
# basic scenarios
|
64
77
|
|
65
78
|
test 'belongs_to should generate a foreign key' do
|
66
79
|
given <<-CODE
|
67
|
-
class Author <
|
68
|
-
class Book <
|
80
|
+
class Author < ActiveRecord::Base; end
|
81
|
+
class Book < ActiveRecord::Base
|
69
82
|
belongs_to :guy, :class_name => 'Author', :foreign_key => 'author_id'
|
70
83
|
end
|
71
84
|
CODE
|
72
85
|
|
73
|
-
keys = Immigrant.infer_keys([]).first
|
74
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
75
86
|
assert_equal(
|
76
87
|
[foreign_key_definition(
|
77
88
|
'books', 'authors',
|
78
|
-
:column => 'author_id', :primary_key => 'id'
|
89
|
+
:column => 'author_id', :primary_key => 'id'
|
79
90
|
)],
|
80
|
-
|
91
|
+
infer_keys
|
81
92
|
)
|
82
93
|
end
|
83
94
|
|
84
95
|
test 'has_one should generate a foreign key' do
|
85
96
|
given <<-CODE
|
86
|
-
class Author <
|
97
|
+
class Author < ActiveRecord::Base
|
87
98
|
has_one :piece_de_resistance, :class_name => 'Book', :order => "id DESC"
|
88
99
|
end
|
89
|
-
class Book <
|
100
|
+
class Book < ActiveRecord::Base; end
|
90
101
|
CODE
|
91
102
|
|
92
|
-
keys = Immigrant.infer_keys([]).first
|
93
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
94
103
|
assert_equal(
|
95
104
|
[foreign_key_definition(
|
96
105
|
'books', 'authors',
|
97
|
-
:column => 'author_id', :primary_key => 'id'
|
106
|
+
:column => 'author_id', :primary_key => 'id'
|
98
107
|
)],
|
99
|
-
|
108
|
+
infer_keys
|
100
109
|
)
|
101
110
|
end
|
102
111
|
|
103
|
-
test 'has_one :dependent => :delete should generate a foreign key with :on_delete => :
|
112
|
+
test 'has_one :dependent => :delete should generate a foreign key with :on_delete => :cascade' do
|
104
113
|
given <<-CODE
|
105
|
-
class Author <
|
114
|
+
class Author < ActiveRecord::Base
|
106
115
|
has_one :book, :order => "id DESC", :dependent => :delete
|
107
116
|
end
|
108
|
-
class Book <
|
117
|
+
class Book < ActiveRecord::Base; end
|
109
118
|
CODE
|
110
119
|
|
111
|
-
keys = Immigrant.infer_keys([]).first
|
112
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
113
120
|
assert_equal(
|
114
121
|
[foreign_key_definition(
|
115
122
|
'books', 'authors',
|
116
|
-
:column => 'author_id', :primary_key => 'id',
|
123
|
+
:column => 'author_id', :primary_key => 'id', :on_delete => :cascade, :on_update => :cascade
|
117
124
|
)],
|
118
|
-
|
125
|
+
infer_keys
|
119
126
|
)
|
120
127
|
end
|
121
128
|
|
122
129
|
test 'has_many should generate a foreign key' do
|
123
130
|
given <<-CODE
|
124
|
-
class Author <
|
131
|
+
class Author < ActiveRecord::Base
|
125
132
|
has_many :babies, :class_name => 'Book'
|
126
133
|
end
|
127
|
-
class Book <
|
134
|
+
class Book < ActiveRecord::Base; end
|
128
135
|
CODE
|
129
136
|
|
130
|
-
keys = Immigrant.infer_keys([]).first
|
131
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
132
137
|
assert_equal(
|
133
138
|
[foreign_key_definition(
|
134
139
|
'books', 'authors',
|
135
|
-
:column => 'author_id', :primary_key => 'id'
|
140
|
+
:column => 'author_id', :primary_key => 'id'
|
136
141
|
)],
|
137
|
-
|
142
|
+
infer_keys
|
138
143
|
)
|
139
144
|
end
|
140
145
|
|
141
|
-
test 'has_many :dependent => :delete_all should generate a foreign key with :on_delete => :
|
146
|
+
test 'has_many :dependent => :delete_all should generate a foreign key with :on_delete => :cascade' do
|
142
147
|
given <<-CODE
|
143
|
-
class Author <
|
148
|
+
class Author < ActiveRecord::Base
|
144
149
|
has_many :books, :dependent => :delete_all
|
145
150
|
end
|
146
|
-
class Book <
|
151
|
+
class Book < ActiveRecord::Base; end
|
147
152
|
CODE
|
148
153
|
|
149
|
-
keys = Immigrant.infer_keys([]).first
|
150
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
151
154
|
assert_equal(
|
152
155
|
[foreign_key_definition(
|
153
156
|
'books', 'authors',
|
154
|
-
:column => 'author_id', :primary_key => 'id',
|
157
|
+
:column => 'author_id', :primary_key => 'id', :on_delete => :cascade, :on_update => :cascade
|
155
158
|
)],
|
156
|
-
|
159
|
+
infer_keys
|
157
160
|
)
|
158
161
|
end
|
159
162
|
|
160
163
|
test 'has_and_belongs_to_many should generate two foreign keys' do
|
161
164
|
given <<-CODE
|
162
|
-
class Author <
|
165
|
+
class Author < ActiveRecord::Base
|
163
166
|
has_and_belongs_to_many :fans
|
164
167
|
end
|
165
|
-
class Fan <
|
168
|
+
class Fan < ActiveRecord::Base; end
|
166
169
|
CODE
|
167
170
|
|
168
|
-
keys = Immigrant.infer_keys([]).first
|
169
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
170
171
|
assert_equal(
|
171
172
|
[foreign_key_definition(
|
172
173
|
'authors_fans', 'authors',
|
173
|
-
:column => 'author_id', :primary_key => 'id'
|
174
|
+
:column => 'author_id', :primary_key => 'id'
|
174
175
|
),
|
175
176
|
foreign_key_definition(
|
176
177
|
'authors_fans', 'fans',
|
177
|
-
:column => 'fan_id', :primary_key => 'id'
|
178
|
+
:column => 'fan_id', :primary_key => 'id'
|
178
179
|
)],
|
179
|
-
|
180
|
+
infer_keys
|
180
181
|
)
|
181
182
|
end
|
182
183
|
|
183
184
|
test 'has_and_belongs_to_many should respect the join_table' do
|
184
185
|
given <<-CODE
|
185
|
-
class Author <
|
186
|
+
class Author < ActiveRecord::Base
|
186
187
|
has_and_belongs_to_many :fans, :join_table => :lols_wuts
|
187
188
|
end
|
188
|
-
class Fan <
|
189
|
+
class Fan < ActiveRecord::Base; end
|
189
190
|
CODE
|
190
191
|
|
191
|
-
keys = Immigrant.infer_keys([]).first
|
192
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
193
192
|
assert_equal(
|
194
193
|
[foreign_key_definition(
|
195
194
|
'lols_wuts', 'authors',
|
196
|
-
:column => 'author_id', :primary_key => 'id'
|
195
|
+
:column => 'author_id', :primary_key => 'id'
|
197
196
|
),
|
198
197
|
foreign_key_definition(
|
199
198
|
'lols_wuts', 'fans',
|
200
|
-
:column => 'fan_id', :primary_key => 'id'
|
199
|
+
:column => 'fan_id', :primary_key => 'id'
|
201
200
|
)],
|
202
|
-
|
201
|
+
infer_keys
|
203
202
|
)
|
204
203
|
end
|
205
204
|
|
206
205
|
test 'conditional has_one/has_many associations should ignore :dependent' do
|
207
206
|
given <<-CODE
|
208
|
-
class Author <
|
207
|
+
class Author < ActiveRecord::Base
|
209
208
|
has_many :articles, :conditions => "published", :dependent => :delete_all
|
210
209
|
has_one :favorite_book, :class_name => 'Book',
|
211
210
|
:conditions => "most_awesome", :dependent => :delete
|
212
211
|
end
|
213
|
-
class Book <
|
214
|
-
class Article <
|
212
|
+
class Book < ActiveRecord::Base; end
|
213
|
+
class Article < ActiveRecord::Base; end
|
215
214
|
CODE
|
216
215
|
|
217
|
-
keys = Immigrant.infer_keys([]).first
|
218
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
219
216
|
assert_equal(
|
220
217
|
[foreign_key_definition(
|
221
218
|
'articles', 'authors',
|
222
|
-
:column => 'author_id', :primary_key => 'id'
|
219
|
+
:column => 'author_id', :primary_key => 'id'
|
223
220
|
),
|
224
221
|
foreign_key_definition(
|
225
222
|
'books', 'authors',
|
226
|
-
:column => 'author_id', :primary_key => 'id'
|
223
|
+
:column => 'author_id', :primary_key => 'id'
|
227
224
|
)],
|
228
|
-
|
225
|
+
infer_keys
|
229
226
|
)
|
230
227
|
end
|
231
228
|
|
232
229
|
test 'primary_key should be respected' do
|
233
230
|
given <<-CODE
|
234
|
-
class User <
|
231
|
+
class User < ActiveRecord::Base
|
235
232
|
has_many :emails, :primary_key => :email, :foreign_key => :to,
|
236
233
|
:dependent => :destroy
|
237
234
|
end
|
238
|
-
class Email <
|
235
|
+
class Email < ActiveRecord::Base
|
239
236
|
belongs_to :user, :primary_key => :email, :foreign_key => :to
|
240
237
|
end
|
241
238
|
CODE
|
242
239
|
|
243
|
-
keys = Immigrant.infer_keys([]).first
|
244
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
245
240
|
assert_equal(
|
246
241
|
[foreign_key_definition(
|
247
242
|
'emails', 'users',
|
248
|
-
:column => 'to', :primary_key => 'email'
|
243
|
+
:column => 'to', :primary_key => 'email'
|
249
244
|
)],
|
250
|
-
|
245
|
+
infer_keys
|
251
246
|
)
|
252
247
|
end
|
253
248
|
|
@@ -255,64 +250,58 @@ class ImmigrantTest < ActiveSupport::TestCase
|
|
255
250
|
|
256
251
|
test 'STI should not generate duplicate foreign keys' do
|
257
252
|
given <<-CODE
|
258
|
-
class Company <
|
259
|
-
class Employee <
|
253
|
+
class Company < ActiveRecord::Base; end
|
254
|
+
class Employee < ActiveRecord::Base
|
260
255
|
belongs_to :company
|
261
256
|
end
|
262
257
|
class Manager < Employee; end
|
263
258
|
CODE
|
264
259
|
|
265
260
|
assert(Manager.reflections.present?)
|
266
|
-
keys = Immigrant.infer_keys([]).first
|
267
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
268
261
|
assert_equal(
|
269
262
|
[foreign_key_definition(
|
270
263
|
'employees', 'companies',
|
271
|
-
:column => 'company_id', :primary_key => 'id'
|
264
|
+
:column => 'company_id', :primary_key => 'id'
|
272
265
|
)],
|
273
|
-
|
266
|
+
infer_keys
|
274
267
|
)
|
275
268
|
end
|
276
269
|
|
277
270
|
test 'complementary associations should not generate duplicate foreign keys' do
|
278
271
|
given <<-CODE
|
279
|
-
class Author <
|
272
|
+
class Author < ActiveRecord::Base
|
280
273
|
has_many :books
|
281
274
|
end
|
282
|
-
class Book <
|
275
|
+
class Book < ActiveRecord::Base
|
283
276
|
belongs_to :author
|
284
277
|
end
|
285
278
|
CODE
|
286
279
|
|
287
|
-
keys = Immigrant.infer_keys([]).first
|
288
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
289
280
|
assert_equal(
|
290
281
|
[foreign_key_definition(
|
291
282
|
'books', 'authors',
|
292
|
-
:column => 'author_id', :primary_key => 'id'
|
283
|
+
:column => 'author_id', :primary_key => 'id'
|
293
284
|
)],
|
294
|
-
|
285
|
+
infer_keys
|
295
286
|
)
|
296
287
|
end
|
297
288
|
|
298
289
|
test 'redundant associations should not generate duplicate foreign keys' do
|
299
290
|
given <<-CODE
|
300
|
-
class Author <
|
291
|
+
class Author < ActiveRecord::Base
|
301
292
|
has_many :books
|
302
293
|
has_many :favorite_books, :class_name => 'Book', :conditions => "awesome"
|
303
294
|
has_many :bad_books, :class_name => 'Book', :conditions => "amateur_hour"
|
304
295
|
end
|
305
|
-
class Book <
|
296
|
+
class Book < ActiveRecord::Base; end
|
306
297
|
CODE
|
307
298
|
|
308
|
-
keys = Immigrant.infer_keys([]).first
|
309
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
310
299
|
assert_equal(
|
311
300
|
[foreign_key_definition(
|
312
301
|
'books', 'authors',
|
313
|
-
:column => 'author_id', :primary_key => 'id'
|
302
|
+
:column => 'author_id', :primary_key => 'id'
|
314
303
|
)],
|
315
|
-
|
304
|
+
infer_keys
|
316
305
|
)
|
317
306
|
end
|
318
307
|
|
@@ -323,33 +312,32 @@ class ImmigrantTest < ActiveSupport::TestCase
|
|
323
312
|
database_keys = [
|
324
313
|
foreign_key_definition(
|
325
314
|
'articles', 'authors',
|
326
|
-
:column => 'author_id', :primary_key => 'id',
|
315
|
+
:column => 'author_id', :primary_key => 'id',
|
327
316
|
:name => "doesn't_matter"
|
328
317
|
),
|
329
318
|
foreign_key_definition(
|
330
319
|
'books', 'authors', :column => 'author_id', :primary_key => 'id',
|
331
|
-
|
320
|
+
:on_delete => :restrict, :on_update => :nullify
|
332
321
|
)
|
333
322
|
]
|
334
323
|
|
335
324
|
given <<-CODE
|
336
|
-
class Author <
|
325
|
+
class Author < ActiveRecord::Base
|
337
326
|
has_many :articles
|
338
327
|
has_one :favorite_book, :class_name => 'Book',
|
339
328
|
:conditions => "most_awesome"
|
340
329
|
end
|
341
|
-
class Book <
|
342
|
-
class Article <
|
330
|
+
class Book < ActiveRecord::Base; end
|
331
|
+
class Article < ActiveRecord::Base; end
|
343
332
|
CODE
|
344
333
|
|
345
|
-
|
346
|
-
assert_equal([], keys)
|
334
|
+
assert_equal([], infer_keys(database_keys))
|
347
335
|
end
|
348
336
|
|
349
337
|
if ActiveRecord::VERSION::STRING < '4.'
|
350
338
|
test 'finder_sql associations should not generate foreign keys' do
|
351
339
|
given <<-CODE
|
352
|
-
class Author <
|
340
|
+
class Author < ActiveRecord::Base
|
353
341
|
has_many :books, :finder_sql => <<-SQL
|
354
342
|
SELECT *
|
355
343
|
FROM books
|
@@ -357,79 +345,113 @@ class ImmigrantTest < ActiveSupport::TestCase
|
|
357
345
|
ORDER BY RANDOM() LIMIT 5'
|
358
346
|
SQL
|
359
347
|
end
|
360
|
-
class Book <
|
348
|
+
class Book < ActiveRecord::Base; end
|
361
349
|
CODE
|
362
350
|
|
363
|
-
|
364
|
-
assert_equal([], keys)
|
351
|
+
assert_equal([], infer_keys)
|
365
352
|
end
|
366
353
|
end
|
367
354
|
|
368
355
|
test 'polymorphic associations should not generate foreign keys' do
|
369
356
|
given <<-CODE
|
370
|
-
class Property <
|
357
|
+
class Property < ActiveRecord::Base
|
371
358
|
belongs_to :owner, :polymorphic => true
|
372
359
|
end
|
373
|
-
class Person <
|
360
|
+
class Person < ActiveRecord::Base
|
374
361
|
has_many :properties, :as => :owner
|
375
362
|
end
|
376
|
-
class Corporation <
|
363
|
+
class Corporation < ActiveRecord::Base
|
377
364
|
has_many :properties, :as => :owner
|
378
365
|
end
|
379
366
|
CODE
|
380
367
|
|
381
|
-
|
382
|
-
assert_equal([], keys)
|
368
|
+
assert_equal([], infer_keys)
|
383
369
|
end
|
384
370
|
|
385
371
|
test 'has_many :through should not generate foreign keys' do
|
386
372
|
given <<-CODE
|
387
|
-
class Author <
|
373
|
+
class Author < ActiveRecord::Base
|
388
374
|
has_many :authors_fans
|
389
375
|
has_many :fans, :through => :authors_fans
|
390
376
|
end
|
391
|
-
class AuthorsFan <
|
377
|
+
class AuthorsFan < ActiveRecord::Base
|
392
378
|
belongs_to :author
|
393
379
|
belongs_to :fan
|
394
380
|
end
|
395
|
-
class Fan <
|
381
|
+
class Fan < ActiveRecord::Base
|
396
382
|
has_many :authors_fans
|
397
383
|
has_many :authors, :through => :authors_fans
|
398
384
|
end
|
399
385
|
CODE
|
400
386
|
|
401
|
-
keys = Immigrant.infer_keys([]).first
|
402
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
403
387
|
assert_equal(
|
404
388
|
[foreign_key_definition(
|
405
389
|
'authors_fans', 'authors',
|
406
|
-
:column => 'author_id', :primary_key => 'id'
|
390
|
+
:column => 'author_id', :primary_key => 'id'
|
407
391
|
),
|
408
392
|
foreign_key_definition(
|
409
393
|
'authors_fans', 'fans',
|
410
|
-
:column => 'fan_id', :primary_key => 'id'
|
394
|
+
:column => 'fan_id', :primary_key => 'id'
|
411
395
|
)],
|
412
|
-
|
396
|
+
infer_keys
|
413
397
|
)
|
414
398
|
end
|
415
399
|
|
416
400
|
test 'broken associations should not cause errors' do
|
417
401
|
given <<-CODE
|
418
|
-
class Author <
|
419
|
-
class Book <
|
402
|
+
class Author < ActiveRecord::Base; end
|
403
|
+
class Book < ActiveRecord::Base
|
420
404
|
belongs_to :author
|
421
405
|
belongs_to :invalid
|
422
406
|
end
|
423
407
|
CODE
|
424
408
|
|
425
|
-
keys = Immigrant.infer_keys([]).first
|
426
|
-
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
427
409
|
assert_equal(
|
428
410
|
[foreign_key_definition(
|
429
411
|
'books', 'authors',
|
430
|
-
:column => 'author_id', :primary_key => 'id'
|
412
|
+
:column => 'author_id', :primary_key => 'id'
|
431
413
|
)],
|
432
|
-
|
414
|
+
infer_keys
|
433
415
|
)
|
434
416
|
end
|
417
|
+
|
418
|
+
test 'abstract classes should not generate a foreign key' do
|
419
|
+
given <<-CODE
|
420
|
+
class User < ActiveRecord::Base; end
|
421
|
+
class Widget < ActiveRecord::Base
|
422
|
+
self.abstract_class = true
|
423
|
+
|
424
|
+
belongs_to :user
|
425
|
+
end
|
426
|
+
CODE
|
427
|
+
|
428
|
+
assert_equal([], infer_keys)
|
429
|
+
end
|
430
|
+
|
431
|
+
test 'missing tables should not generate a foreign key' do
|
432
|
+
given <<-CODE
|
433
|
+
class User < ActiveRecord::Base; end
|
434
|
+
class Widget < ActiveRecord::Base
|
435
|
+
self.table_name = :wiiiidgets
|
436
|
+
belongs_to :user
|
437
|
+
end
|
438
|
+
CODE
|
439
|
+
|
440
|
+
MockConnection.stub_any_instance(:tables, ["users"]) do
|
441
|
+
assert_equal([], infer_keys)
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
test 'invalid columns should not generate a foreign key' do
|
446
|
+
given <<-CODE
|
447
|
+
class User < ActiveRecord::Base; end
|
448
|
+
class Widget < ActiveRecord::Base
|
449
|
+
belongs_to :user
|
450
|
+
end
|
451
|
+
CODE
|
452
|
+
|
453
|
+
MockConnection.stub_any_instance(:columns, []) do
|
454
|
+
assert_equal([], infer_keys)
|
455
|
+
end
|
456
|
+
end
|
435
457
|
end
|
metadata
CHANGED
@@ -1,30 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: immigrant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Jon Jensen
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2015-02-24 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activerecord
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '3.0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '3.0'
|
30
27
|
description: Adds a generator for creating a foreign key migration based on your current
|
@@ -35,47 +32,48 @@ extensions: []
|
|
35
32
|
extra_rdoc_files: []
|
36
33
|
files:
|
37
34
|
- LICENSE.txt
|
38
|
-
- Rakefile
|
39
35
|
- README.md
|
36
|
+
- Rakefile
|
40
37
|
- lib/generators/USAGE
|
41
38
|
- lib/generators/immigration_generator.rb
|
42
39
|
- lib/generators/templates/immigration-pre-3.1.rb.erb
|
43
40
|
- lib/generators/templates/immigration.rb.erb
|
41
|
+
- lib/immigrant.rb
|
42
|
+
- lib/immigrant/compat.rb
|
44
43
|
- lib/immigrant/compat/3.0.rb
|
45
44
|
- lib/immigrant/compat/3.1.rb
|
46
45
|
- lib/immigrant/compat/4.0.rb
|
47
46
|
- lib/immigrant/compat/4.2.rb
|
48
|
-
- lib/immigrant/compat/
|
49
|
-
- lib/immigrant/compat.rb
|
47
|
+
- lib/immigrant/compat/5.0.rb
|
48
|
+
- lib/immigrant/compat/active_record.rb
|
49
|
+
- lib/immigrant/compat/foreigner.rb
|
50
|
+
- lib/immigrant/foreign_key_extensions.rb
|
50
51
|
- lib/immigrant/loader.rb
|
51
52
|
- lib/immigrant/railtie.rb
|
52
|
-
- lib/immigrant.rb
|
53
53
|
- test/compat.rb
|
54
54
|
- test/helper.rb
|
55
55
|
- test/immigrant_test.rb
|
56
56
|
homepage: http://github.com/jenseng/immigrant
|
57
57
|
licenses: []
|
58
|
+
metadata: {}
|
58
59
|
post_install_message:
|
59
60
|
rdoc_options: []
|
60
61
|
require_paths:
|
61
62
|
- lib
|
62
63
|
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
-
none: false
|
64
64
|
requirements:
|
65
|
-
- -
|
65
|
+
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
67
|
version: 1.8.7
|
68
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
-
none: false
|
70
69
|
requirements:
|
71
|
-
- -
|
70
|
+
- - ">="
|
72
71
|
- !ruby/object:Gem::Version
|
73
72
|
version: 1.3.5
|
74
73
|
requirements: []
|
75
74
|
rubyforge_project:
|
76
|
-
rubygems_version:
|
75
|
+
rubygems_version: 2.2.2
|
77
76
|
signing_key:
|
78
|
-
specification_version:
|
77
|
+
specification_version: 4
|
79
78
|
summary: Foreign key migration generator for Rails
|
80
79
|
test_files: []
|
81
|
-
has_rdoc:
|