@@ -108,41 +108,59 @@ protected function buildDefinition(Model $model)
108
108
$ dataType = 'nullable ' . ucfirst ($ dataType );
109
109
}
110
110
111
+ $ column_definition = self ::INDENT ;
111
112
if ($ dataType === 'bigIncrements ' && $ this ->isLaravel7orNewer ()) {
112
- $ definition .= self :: INDENT . '$table->id( ' ;
113
+ $ column_definition .= '$table->id( ' ;
113
114
} else {
114
- $ definition .= self :: INDENT . '$table-> ' . $ dataType . "(' {$ column ->name ()}' " ;
115
+ $ column_definition .= '$table-> ' . $ dataType . "(' {$ column ->name ()}' " ;
115
116
}
116
117
117
118
if (!empty ($ column ->attributes ()) && !in_array ($ column ->dataType (), ['id ' , 'uuid ' ])) {
118
- $ definition .= ', ' ;
119
+ $ column_definition .= ', ' ;
119
120
if (in_array ($ column ->dataType (), ['set ' , 'enum ' ])) {
120
- $ definition .= json_encode ($ column ->attributes ());
121
+ $ column_definition .= json_encode ($ column ->attributes ());
121
122
} else {
122
- $ definition .= implode (', ' , $ column ->attributes ());
123
+ $ column_definition .= implode (', ' , $ column ->attributes ());
123
124
}
124
125
}
125
- $ definition .= ') ' ;
126
+ $ column_definition .= ') ' ;
127
+
128
+ $ modifiers = $ column ->modifiers ();
126
129
127
130
$ foreign = '' ;
131
+ $ foreign_modifier = $ column ->isForeignKey ();
132
+
133
+ if ($ this ->shouldAddForeignKeyConstraint ($ column )) {
134
+ $ foreign = $ this ->buildForeignKey ($ column ->name (), $ foreign_modifier === 'foreign ' ? null : $ foreign_modifier , $ column ->dataType ());
135
+ if ($ column ->dataType () === 'id ' && $ this ->isLaravel7orNewer ()) {
136
+ $ column_definition = $ foreign ;
137
+ $ foreign = '' ;
138
+ }
139
+
140
+ // TODO: unset the proper modifier
141
+ $ modifiers = collect ($ modifiers )->reject (function ($ modifier ) {
142
+ return (is_array ($ modifier ) && key ($ modifier ) === 'foreign ' ) || $ modifier === 'foreign ' ;
143
+ });
144
+ }
128
145
129
- foreach ($ column -> modifiers () as $ modifier ) {
146
+ foreach ($ modifiers as $ modifier ) {
130
147
if (is_array ($ modifier )) {
131
- if (key ($ modifier ) === 'foreign ' ) {
132
- $ foreign = self ::INDENT . '$table->foreign( ' . "' {$ column ->name ()}')->references('id')->on(' " . Str::lower (Str::plural (current ($ modifier ))) . "')->onDelete('cascade'); " . PHP_EOL ;
133
- } else {
134
- $ definition .= '-> ' . key ($ modifier ) . '( ' . current ($ modifier ) . ') ' ;
135
- }
148
+ $ column_definition .= '-> ' . key ($ modifier ) . '( ' . current ($ modifier ) . ') ' ;
136
149
} elseif ($ modifier === 'unsigned ' && Str::startsWith ($ dataType , 'unsigned ' )) {
137
150
continue ;
138
151
} elseif ($ modifier === 'nullable ' && Str::startsWith ($ dataType , 'nullable ' )) {
139
152
continue ;
140
153
} else {
141
- $ definition .= '-> ' . $ modifier . '() ' ;
154
+ $ column_definition .= '-> ' . $ modifier . '() ' ;
142
155
}
143
156
}
144
157
145
- $ definition .= '; ' . PHP_EOL . $ foreign ;
158
+ $ column_definition .= '; ' . PHP_EOL ;
159
+ if (!empty ($ foreign )) {
160
+ $ column_definition .= $ foreign . '; ' . PHP_EOL ;
161
+ }
162
+
163
+ $ definition .= $ column_definition ;
146
164
}
147
165
148
166
if ($ model ->usesSoftDeletes ()) {
@@ -156,18 +174,57 @@ protected function buildDefinition(Model $model)
156
174
return trim ($ definition );
157
175
}
158
176
159
- protected function buildPivotTableDefinition (array $ segments, $ dataType = ' unsignedBigInteger ' )
177
+ protected function buildPivotTableDefinition (array $ segments )
160
178
{
161
179
$ definition = '' ;
162
180
163
181
foreach ($ segments as $ segment ) {
164
- $ column = strtolower ($ segment ) . '_id ' ;
165
- $ definition .= self ::INDENT . '$table-> ' . $ dataType . "(' {$ column }'); " . PHP_EOL ;
182
+ $ column = Str::lower ($ segment );
183
+ $ references = 'id ' ;
184
+ $ on = Str::plural ($ column );
185
+ $ foreign = Str::singular ($ column ) . '_ ' . $ references ;
186
+
187
+ if (!$ this ->isLaravel7orNewer ()) {
188
+ $ definition .= self ::INDENT . '$table->unsignedBigInteger( \'' . $ foreign . '\'); ' . PHP_EOL ;
189
+ }
190
+
191
+ if (config ('blueprint.use_constraints ' )) {
192
+ $ definition .= $ this ->buildForeignKey ($ foreign , $ on , 'id ' ) . '; ' . PHP_EOL ;
193
+ } elseif ($ this ->isLaravel7orNewer ()) {
194
+ $ definition .= self ::INDENT . '$table->foreignId( \'' . $ foreign . '\'); ' . PHP_EOL ;
195
+ }
166
196
}
167
197
168
198
return trim ($ definition );
169
199
}
170
200
201
+ protected function buildForeignKey (string $ column_name , ?string $ on , string $ type )
202
+ {
203
+ if (is_null ($ on )) {
204
+ $ table = Str::plural (Str::beforeLast ($ column_name , '_ ' ));
205
+ $ column = Str::afterLast ($ column_name , '_ ' );
206
+ } elseif (Str::contains ($ on , '. ' )) {
207
+ [$ table , $ column ] = explode ('. ' , $ on );
208
+ $ table = Str::snake ($ table );
209
+ } else {
210
+ $ table = Str::plural ($ on );
211
+ $ column = Str::afterLast ($ column_name , '_ ' );
212
+ }
213
+
214
+ if ($ this ->isLaravel7orNewer () && $ type === 'id ' ) {
215
+ if ($ column_name === Str::singular ($ table ) . '_ ' . $ column ) {
216
+ return self ::INDENT . '$table->foreignId ' . "(' {$ column_name }')->constrained()->cascadeOnDelete() " ;
217
+ }
218
+ if ($ column === 'id ' ) {
219
+ return self ::INDENT . '$table->foreignId ' . "(' {$ column_name }')->constrained(' {$ table }')->cascadeOnDelete() " ;
220
+ }
221
+
222
+ return self ::INDENT . '$table->foreignId ' . "(' {$ column_name }')->constrained(' {$ table }', ' {$ column }')->cascadeOnDelete()) " ;
223
+ }
224
+
225
+ return self ::INDENT . '$table->foreign ' . "(' {$ column_name }')->references(' {$ column }')->on(' {$ table }')->onDelete('cascade') " ;
226
+ }
227
+
171
228
protected function getClassName (Model $ model )
172
229
{
173
230
return 'Create ' . Str::studly ($ model ->tableName ()) . 'Table ' ;
@@ -201,4 +258,17 @@ protected function getPivotTableName(array $segments)
201
258
sort ($ segments );
202
259
return strtolower (implode ('_ ' , $ segments ));
203
260
}
261
+
262
+ private function shouldAddForeignKeyConstraint (\Blueprint \Models \Column $ column )
263
+ {
264
+ if ($ column ->name () === 'id ' ) {
265
+ return false ;
266
+ }
267
+
268
+ if ($ column ->isForeignKey ()) {
269
+ return true ;
270
+ }
271
+
272
+ return in_array ($ column ->dataType (), ['id ' , 'uuid ' ]) && config ('blueprint.use_constraints ' );
273
+ }
204
274
}
0 commit comments