immigrant 0.1.5 → 0.1.6
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/lib/immigrant.rb +80 -44
- data/test/immigrant_test.rb +19 -0
- metadata +3 -3
data/lib/immigrant.rb
CHANGED
@@ -50,16 +50,14 @@ module Immigrant
|
|
50
50
|
# see what the models say there should be
|
51
51
|
foreign_keys = {}
|
52
52
|
warnings = {}
|
53
|
-
|
54
|
-
|
55
|
-
}.flatten.uniq.each do |foreign_key|
|
53
|
+
|
54
|
+
candidate_model_keys(classes).each do |foreign_key|
|
56
55
|
# we may have inferred it from several different places, e.g.
|
57
56
|
# Bar.belongs_to :foo
|
58
57
|
# Foo.has_many :bars
|
59
58
|
# Foo.has_many :bazzes, :class_name => Bar
|
60
59
|
# we need to make sure everything is legit and see if any of them
|
61
60
|
# specify :dependent => :delete
|
62
|
-
next if foreign_key.nil?
|
63
61
|
if current_key = foreign_keys[foreign_key.hash_key]
|
64
62
|
if current_key.to_table != foreign_key.to_table || current_key.options[:primary_key] != foreign_key.options[:primary_key]
|
65
63
|
warnings[foreign_key.hash_key] ||= "Skipping #{foreign_key.from_table}.#{foreign_key.options[:column]}: it has multiple associations referencing different keys/tables."
|
@@ -74,56 +72,94 @@ module Immigrant
|
|
74
72
|
[foreign_keys, warnings]
|
75
73
|
end
|
76
74
|
|
77
|
-
def
|
78
|
-
|
75
|
+
def candidate_model_keys(classes)
|
76
|
+
classes.inject([]) do |result, klass|
|
77
|
+
result.concat foreign_keys_for(klass)
|
78
|
+
end.uniq
|
79
|
+
end
|
79
80
|
|
80
|
-
|
81
|
+
def candidate_reflections_for(klass)
|
82
|
+
klass.reflections.values.reject do |reflection|
|
81
83
|
# some associations can just be ignored, since:
|
82
84
|
# 1. we aren't going to parse SQL
|
83
85
|
# 2. foreign keys for :through associations will be handled by their
|
84
86
|
# component has_one/has_many/belongs_to associations
|
85
87
|
# 3. :polymorphic(/:as) associations can't have foreign keys
|
86
88
|
(reflection.options.keys & [:finder_sql, :through, :polymorphic, :as]).present?
|
87
|
-
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def foreign_keys_for(klass)
|
93
|
+
candidate_reflections_for(klass).inject([]) do |result, reflection|
|
88
94
|
begin
|
89
|
-
|
90
|
-
when :belongs_to
|
91
|
-
Foreigner::ConnectionAdapters::ForeignKeyDefinition.new(
|
92
|
-
klass.table_name, reflection.klass.table_name,
|
93
|
-
:column => reflection.send(fk_method).to_s,
|
94
|
-
:primary_key => reflection.klass.primary_key.to_s,
|
95
|
-
# although belongs_to can specify :dependent, it doesn't make
|
96
|
-
# sense from a foreign key perspective
|
97
|
-
:dependent => nil
|
98
|
-
)
|
99
|
-
when :has_one, :has_many
|
100
|
-
Foreigner::ConnectionAdapters::ForeignKeyDefinition.new(
|
101
|
-
reflection.klass.table_name, klass.table_name,
|
102
|
-
:column => reflection.send(fk_method).to_s,
|
103
|
-
:primary_key => klass.primary_key.to_s,
|
104
|
-
:dependent => [:delete, :delete_all].include?(reflection.options[:dependent]) && !qualified_reflection?(reflection, klass) ? :delete : nil
|
105
|
-
)
|
106
|
-
when :has_and_belongs_to_many
|
107
|
-
join_table = (reflection.respond_to?(:join_table) ? reflection.join_table : reflection.options[:join_table]).to_s
|
108
|
-
[
|
109
|
-
Foreigner::ConnectionAdapters::ForeignKeyDefinition.new(
|
110
|
-
join_table, klass.table_name,
|
111
|
-
:column => reflection.send(fk_method).to_s,
|
112
|
-
:primary_key => klass.primary_key.to_s,
|
113
|
-
:dependent => nil
|
114
|
-
),
|
115
|
-
Foreigner::ConnectionAdapters::ForeignKeyDefinition.new(
|
116
|
-
join_table, reflection.klass.table_name,
|
117
|
-
:column => reflection.association_foreign_key.to_s,
|
118
|
-
:primary_key => reflection.klass.primary_key.to_s,
|
119
|
-
:dependent => nil
|
120
|
-
)
|
121
|
-
]
|
122
|
-
end
|
95
|
+
result.concat foreign_key_for(klass, reflection)
|
123
96
|
rescue NameError # e.g. belongs_to :oops_this_is_not_a_table
|
124
|
-
|
97
|
+
result
|
125
98
|
end
|
126
|
-
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def foreign_key_for(klass, reflection)
|
103
|
+
case reflection.macro
|
104
|
+
when :belongs_to
|
105
|
+
infer_belongs_to_keys(klass, reflection)
|
106
|
+
when :has_one, :has_many
|
107
|
+
infer_has_n_keys(klass, reflection)
|
108
|
+
when :has_and_belongs_to_many
|
109
|
+
infer_habtm_keys(klass, reflection)
|
110
|
+
else
|
111
|
+
[]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def infer_belongs_to_keys(klass, reflection)
|
116
|
+
[
|
117
|
+
Foreigner::ConnectionAdapters::ForeignKeyDefinition.new(
|
118
|
+
klass.table_name,
|
119
|
+
reflection.klass.table_name,
|
120
|
+
:column => reflection.send(fk_method).to_s,
|
121
|
+
:primary_key => (reflection.options[:primary_key] || reflection.klass.primary_key).to_s,
|
122
|
+
# although belongs_to can specify :dependent, it doesn't make
|
123
|
+
# sense from a foreign key perspective
|
124
|
+
:dependent => nil
|
125
|
+
)
|
126
|
+
]
|
127
|
+
end
|
128
|
+
|
129
|
+
def infer_has_n_keys(klass, reflection)
|
130
|
+
[
|
131
|
+
Foreigner::ConnectionAdapters::ForeignKeyDefinition.new(
|
132
|
+
reflection.klass.table_name,
|
133
|
+
klass.table_name,
|
134
|
+
:column => reflection.send(fk_method).to_s,
|
135
|
+
:primary_key => (reflection.options[:primary_key] || klass.primary_key).to_s,
|
136
|
+
:dependent => [:delete, :delete_all].include?(reflection.options[:dependent]) && !qualified_reflection?(reflection, klass) ? :delete : nil
|
137
|
+
)
|
138
|
+
]
|
139
|
+
end
|
140
|
+
|
141
|
+
def infer_habtm_keys(klass, reflection)
|
142
|
+
join_table = (reflection.respond_to?(:join_table) ? reflection.join_table : reflection.options[:join_table]).to_s
|
143
|
+
[
|
144
|
+
Foreigner::ConnectionAdapters::ForeignKeyDefinition.new(
|
145
|
+
join_table,
|
146
|
+
klass.table_name,
|
147
|
+
:column => reflection.send(fk_method).to_s,
|
148
|
+
:primary_key => klass.primary_key.to_s,
|
149
|
+
:dependent => nil
|
150
|
+
),
|
151
|
+
Foreigner::ConnectionAdapters::ForeignKeyDefinition.new(
|
152
|
+
join_table,
|
153
|
+
reflection.klass.table_name,
|
154
|
+
:column => reflection.association_foreign_key.to_s,
|
155
|
+
:primary_key => reflection.klass.primary_key.to_s,
|
156
|
+
:dependent => nil
|
157
|
+
)
|
158
|
+
]
|
159
|
+
end
|
160
|
+
|
161
|
+
def fk_method
|
162
|
+
ActiveRecord::VERSION::STRING < '3.1.' ? :primary_key_name : :foreign_key
|
127
163
|
end
|
128
164
|
|
129
165
|
def qualified_reflection?(reflection, klass)
|
data/test/immigrant_test.rb
CHANGED
@@ -202,6 +202,25 @@ class ImmigrantTest < ActiveSupport::TestCase
|
|
202
202
|
)
|
203
203
|
end
|
204
204
|
|
205
|
+
test 'primary_key should be respected' do
|
206
|
+
class User < MockModel
|
207
|
+
has_many :emails, :primary_key => :email, :foreign_key => :to,
|
208
|
+
:dependent => :destroy
|
209
|
+
end
|
210
|
+
class Email < MockModel
|
211
|
+
belongs_to :user, :primary_key => :email, :foreign_key => :to
|
212
|
+
end
|
213
|
+
|
214
|
+
keys = Immigrant.infer_keys([]).first
|
215
|
+
assert_nothing_raised { keys.map { |key| key.to_ruby(:add) } }
|
216
|
+
assert_equal(
|
217
|
+
[foreign_key_definition(
|
218
|
+
'emails', 'users',
|
219
|
+
:column => 'to', :primary_key => 'email', :dependent => nil
|
220
|
+
)],
|
221
|
+
keys
|
222
|
+
)
|
223
|
+
end
|
205
224
|
|
206
225
|
# (no) duplication
|
207
226
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: immigrant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-03-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -84,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
84
|
version: 1.3.5
|
85
85
|
requirements: []
|
86
86
|
rubyforge_project:
|
87
|
-
rubygems_version: 1.8.
|
87
|
+
rubygems_version: 1.8.23
|
88
88
|
signing_key:
|
89
89
|
specification_version: 3
|
90
90
|
summary: Migration generator for Foreigner
|