数据库查询多参数,多模型
Database query multiple parameters, multiple models
在我的项目中我有 4 个模型:
- 国家
- 城市
- 酒店
- 房间
所以..一个Country
有很多Cities
,一个City
有很多Hotels
,等等..
现在,我想通过访问 url 来显示包含房间的页面:
example.com/last-minute/{country}/{city}/{hotel}
像 example.com/last-minute/us/nyc/hilton
这样的页面应该显示 us
、nyc
和 hilton
酒店内的所有房间。
现在我需要一个数据库查询来获取我想要显示的数据。
像这样的东西有效:
$rooms = Room::where('hotel_slug', '=', $hotel)->get();
但是当我在阿姆斯特丹也有 Hilton
酒店时,这会产生问题。
我建议您在 Room
模型中创建一个本地范围。
最好使用 joins
而不是 whereHas
(它很慢)。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Room extends Model
{
public function scopeOnPlace($query, $country, $city, $hotel)
{
return $query->select('rooms.*')
->join('hotels', 'rooms.hotel_id', '=', 'hotels.id')
->join('cities', 'hotels.city_id', '=', 'cities.id')
->join('countries', 'cities.country_id', '=', 'countries.id')
->where('countries.slug', $country)
->where('cities.slug', $city)
->where('hotels.slug', $hotel);
}
}
然后你可以像这样使用它:
$rooms = Room::onPlace($country, $city, $hotel)->get();
例如
Route::get('last-minute/{country}/{city}/{hotel}', [LastMinuteController::class, 'show']);
class LastMinuteController extends Controller
{
public function show($country, $city, $hotel)
{
$rooms = Room::onPlace($country, $city, $hotel)->get();
}
}
在我的项目中我有 4 个模型:
- 国家
- 城市
- 酒店
- 房间
所以..一个Country
有很多Cities
,一个City
有很多Hotels
,等等..
现在,我想通过访问 url 来显示包含房间的页面:
example.com/last-minute/{country}/{city}/{hotel}
像 example.com/last-minute/us/nyc/hilton
这样的页面应该显示 us
、nyc
和 hilton
酒店内的所有房间。
现在我需要一个数据库查询来获取我想要显示的数据。
像这样的东西有效:
$rooms = Room::where('hotel_slug', '=', $hotel)->get();
但是当我在阿姆斯特丹也有 Hilton
酒店时,这会产生问题。
我建议您在 Room
模型中创建一个本地范围。
最好使用 joins
而不是 whereHas
(它很慢)。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Room extends Model
{
public function scopeOnPlace($query, $country, $city, $hotel)
{
return $query->select('rooms.*')
->join('hotels', 'rooms.hotel_id', '=', 'hotels.id')
->join('cities', 'hotels.city_id', '=', 'cities.id')
->join('countries', 'cities.country_id', '=', 'countries.id')
->where('countries.slug', $country)
->where('cities.slug', $city)
->where('hotels.slug', $hotel);
}
}
然后你可以像这样使用它:
$rooms = Room::onPlace($country, $city, $hotel)->get();
例如
Route::get('last-minute/{country}/{city}/{hotel}', [LastMinuteController::class, 'show']);
class LastMinuteController extends Controller
{
public function show($country, $city, $hotel)
{
$rooms = Room::onPlace($country, $city, $hotel)->get();
}
}