Laravel 5.6:多表带条件关联——酒店所有者获取关联预订
嘿,针对你的问题,我来一步步给你讲清楚怎么用Laravel Eloquent实现多表关联查询,获取酒店所有者的预订记录~
首先先明确你的数据库关联逻辑:一个用户(酒店所有者)对应多个酒店,一个酒店对应多个房间,一个房间对应多个预订。我们可以通过Eloquent的关联方法把这些关系串联起来,轻松拿到需要的数据。
第一步:给各Model定义Eloquent关联
先在对应的模型文件里添加上关联方法,让Laravel知道表之间的关联关系:
User模型(app/Models/User.php)
namespace App\Models; use Illuminate\Database\Eloquent\Model; class User extends Model { // 一个用户拥有多个酒店 public function hotels() { return $this->hasMany(Hotel::class, 'user_id'); } }
Hotel模型(app/Models/Hotel.php)
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Hotel extends Model { // 酒店属于一个用户 public function user() { return $this->belongsTo(User::class, 'user_id'); } // 一个酒店拥有多个房间 public function rooms() { return $this->hasMany(Room::class, 'hotel_id'); } }
Room模型(app/Models/Room.php)
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Room extends Model { // 房间属于一个酒店 public function hotel() { return $this->belongsTo(Hotel::class, 'hotel_id'); } // 一个房间拥有多个预订 public function bookings() { return $this->hasMany(Booking::class, 'room_id'); } }
Booking模型(app/Models/Booking.php)
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Booking extends Model { // 预订属于一个房间 public function room() { return $this->belongsTo(Room::class, 'room_id'); } // 快捷关联:通过房间直接关联到酒店 public function hotel() { return $this->hasOneThrough(Hotel::class, Room::class, 'hotel_id', 'id', 'room_id', 'hotel_id'); } }
第二步:通过用户ID获取对应酒店的所有预订
这里给你几种常用的实现方式,你可以根据需求选择:
方式1:通过User模型加载嵌套关联(直观易读)
如果需要同时获取用户、酒店、房间的信息,这种方式很合适:
// 替换成实际的酒店所有者ID $ownerId = 1; // 加载用户及其关联的酒店、房间、预订 $hotelOwner = User::with('hotels.rooms.bookings')->find($ownerId); // 把多层嵌套的预订集合扁平化,直接拿到所有预订 $allBookings = $hotelOwner->hotels->flatMap(function ($hotel) { return $hotel->rooms->flatMap(function ($room) { return $room->bookings; }); });
方式2:直接从Booking模型查询(性能更优)
如果只需要预订数据,不需要加载其他关联模型,这种方式会生成更简洁的SQL,性能更好:
$ownerId = 1; // 通过whereHas过滤出属于该用户酒店的预订 $allBookings = Booking::whereHas('room.hotel', function ($query) use ($ownerId) { $query->where('user_id', $ownerId); })->get();
方式3:给User模型添加快捷关联(调用更方便)
你可以在User模型里定义一个直接关联预订的方法,之后调用起来就像获取普通关联一样简单:
// 在User模型里添加这个方法 public function bookings() { return $this->hasManyThrough( Booking::class, Room::class, 'hotel_id', // rooms表关联hotels的外键 'room_id', // bookings表关联rooms的外键 'id', // users表的主键 'hotel_id' // hotels表的主键 )->join('hotels', 'rooms.hotel_id', '=', 'hotels.id') ->where('hotels.user_id', $this->id); } // 之后直接这样调用就能拿到该用户的所有预订 $allBookings = User::find($ownerId)->bookings;
额外:获取单个酒店的所有预订
如果需要单独查询某一个酒店的预订,也很简单:
$hotelId = 1; // 方式1:通过酒店模型加载关联 $hotel = Hotel::with('rooms.bookings')->find($hotelId); $hotelBookings = $hotel->rooms->flatMap(fn($room) => $room->bookings); // 方式2:直接查询Booking $hotelBookings = Booking::whereHas('room', function ($query) use ($hotelId) { $query->where('hotel_id', $hotelId); })->get();
内容的提问来源于stack exchange,提问作者VishnuKumar Pv
相关产品推荐
相关产品推荐

