Laravel/Lumen Eloquent多模型关联:关联三张表返回完整数据
我来帮你搞定这个Laravel/Lumen Eloquent多表关联查询的问题!下面一步步拆解实现方案:
解决Laravel/Lumen多模型关联查询问题
首先咱们先理清楚三张表的关联逻辑:
- 一个客户对应多个网站(
customers→customer_websites是一对多关系) - 一个网站对应一个状态(
customer_websites→customer_websites_status通常是一对一,若需历史状态可调整为一对多)
第一步:定义模型关联
先把三个模型的关联关系配置好,确保外键匹配你的数据库字段:
Customer 模型
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Customer extends Model { protected $table = 'customers'; // 关联客户名下的所有网站 public function websites() { return $this->hasMany(CustomerWebsite::class, 'customer_id'); } }
CustomerWebsite 模型
namespace App\Models; use Illuminate\Database\Eloquent\Model; class CustomerWebsite extends Model { protected $table = 'customer_websites'; // 关联所属客户 public function customer() { return $this->belongsTo(Customer::class, 'customer_id'); } // 关联网站的状态(一对一,若需最新历史状态可加->latest()) public function status() { return $this->hasOne(CustomerWebsiteStatus::class, 'website_id'); // 若需取最新状态:return $this->hasOne(CustomerWebsiteStatus::class, 'website_id')->latest(); } }
CustomerWebsiteStatus 模型
namespace App\Models; use Illuminate\Database\Eloquent\Model; class CustomerWebsiteStatus extends Model { protected $table = 'customer_websites_status'; // 关联所属网站 public function website() { return $this->belongsTo(CustomerWebsite::class, 'website_id'); } }
第二步:控制器查询并格式化返回
在控制器中使用**预加载(Eager Loading)**避免N+1查询问题,同时把数据格式化成你需要的结构:
namespace App\Http\Controllers; use App\Models\Customer; use Illuminate\Http\Response; class CustomerController extends Controller { public function show($customerId) { // 预加载客户的网站,以及每个网站对应的状态 $customer = Customer::with(['websites.status'])->findOrFail($customerId); // 按需求格式化返回数据(可根据你的字段调整) $formattedResponse = [ 'customer_info' => [ 'id' => $customer->id, 'name' => $customer->name, 'email' => $customer->email, // 其他客户字段... ], 'websites' => $customer->websites->map(function ($website) { return [ 'website_id' => $website->id, 'url' => $website->url, 'domain' => $website->domain, // 其他网站字段... 'status' => $website->status ? [ 'status_id' => $website->status->id, 'status_code' => $website->status->status_code, 'status_desc' => $website->status->description, 'updated_at' => $website->status->updated_at // 其他状态字段... ] => null // 处理网站无状态的情况 ]; }) ]; return response()->json($formattedResponse, Response::HTTP_OK); } }
额外优化提示
- 如果需要筛选特定状态的网站,可在预加载时添加条件:
$customer = Customer::with([ 'websites' => function ($query) { $query->where('is_active', true); // 只加载活跃网站 }, 'websites.status' ])->findOrFail($customerId); - 若
customer_websites_status是历史状态表(一个网站有多个状态),可将CustomerWebsite的status关联改为hasMany,再在格式化时取最新一条或全部状态。
内容的提问来源于stack exchange,提问作者user8116198
相关产品推荐
相关产品推荐

