Модель и отношения Ларавела могут здесь сильно помочь.Особенно hasManyThrough
.Посмотрите Документы для более подробного объяснения.
Вам понадобятся три модели: Страна, Штат и Муниципалитет.Вы можете использовать artisan, чтобы сделать это через php artisan make:model modelName
или создать их в своем проекте вручную.В любом случае это должно выглядеть следующим образом:
Модель страны
use Illuminate\Database\Eloquent\Model;
class Country extends Model {
// A Country can have many Municipalities but they do not directly belong
// to the Country they belong to the State -- Which belongs to the Country
public function municipalities() {
return $this->hasManyThrough('App\Municipality', 'App\State');
}
// Each Country can have many States
public function states() {
return $this->hasMany('App\State');
}
}
Модель штата
use Illuminate\Database\Eloquent\Model;
class State extends Model {
// Assuming each State can only belong to One Country
public function country() {
return $this->belongsTo('App\Country');
}
// Each State can have many Municipalities
public function municipalities() {
return $this->hasMany('App\Municipalities');
}
}
Модель муниципалитета
use Illuminate\Database\Eloquent\Model;
class Municipality extends Model {
// Assuming each Municipality can belong to only one State
public function state() {
return $this->belongsTo('App\State');
}
// Should you ever need this Municipality's Country
public function country() {
return $this->state->country;
}
}
Все это работает подПредположим, у вас есть структура таблицы, подобная этой:
страны:
| id | name | another_column |
-----------------------------
1 | USA |
штаты:
| id | country_id | name | another_col |
----------------------------------------
1 | 1 | OK |
муниципалитеты:
| id | state_id | postalcode_id | name | another_col |
------------------------------------------------------
1 | 1 | 1 | OKC |
postal_code:
| id | state_id | postal_code |
-------------------------------
1 | 1 | 73102 |
Что касается вашего контроллера, вы можете разбить его на 3 конечные точки: getCountries
, getStatesByCountry
, getCitiesByState
- каждая получает данные на основе переданного ему идентификатора.
public function getCountries(Request $request) {
$id = $request->get('id');
if ( $id ) {
// Or return some string you want to return
return response()->json(Country::find($id));
}
$countries = Country::all();
// or loop over all $countries and make a string
return response()->json($countries);
}
public function getStatesByCountry(Request $request) {
$id = $request->get('country_id');
return response()->json(Country::find($id)->states);
// Or
// return response()->json(State::where('country_id', '=', $id)->get());
}
public function getCitiesByState(Request $request) {
$id = $request->get('state_id');
return response()->json(State::find($id)->municipalities);
// or return response()->json(Municipality::where('state_id', '=', $id)->get());
}
Каждый раз, когда изменяется один из ваших динамических параметров, вы запрашиваете один шаг ниже.Поэтому, если вы измените страну, вы бы запросили getStatesByCountry
- если вы измените состояние, вы запросите getCitiesByState
.
И наконец, если вы хотите, чтобы все города были разбиты по странам
public function getCitiesByCountry(Request $request) {
$id = $request->get('country_id');
return response()->json(Country::find($id)->municipalities);
}
Редактировать
Вы бы поместили каждую из этих функций в свой контроллер для обработки запросов.Вам также нужно обновить маршруты, web.php
, и добавить маршрут и обработчик для каждой из функций.
// {id?} signifies an optional parameter. Based on the func. passing
// no ID gets all Countries - specifying one only gets the one.
Route::get('/posts/get-countries/{id?}', 'PostController@getCountries');
Route::get('/posts/get-states-by-country/{id}', 'PostController@getStatesByCountry');
Route::get('/posts/get-cities-by-state/{id}', 'PostController@getCitiesByState');