You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:17:29