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

Laravel Eloquent关联查询:获取站点数据及关联公司名称

在Laravel中用Eloquent获取带公司名称的站点数据

嘿,我来帮你搞定这个需求!在Laravel里用Eloquent关联获取站点并附带公司名称其实有几种实用的方法,我一个个给你拆解:

方法一:预加载关联+数据映射(最直观)

首先确保你的模型关联已经正确定义(你已经提到了,不过再确认下更稳妥):

Site模型的关联方法

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Site extends Model
{
    // ... 其他模型代码

    public function company(): BelongsTo
    {
        return $this->belongsTo(Company::class);
    }
}

控制器中获取并格式化数据

我们用with('company')预加载关联,避免N+1查询问题,再通过map方法把公司名称合并到站点数据里:

use App\Models\Site;
use Illuminate\Http\Response;

public function getSitesWithCompany()
{
    // 预加载公司关联,可选指定只查询需要的字段优化性能
    $sites = Site::with('company:id,name')->get();

    // 格式化数据,把公司名称加入返回数组
    $formattedSites = $sites->map(function ($site) {
        // 合并原站点数据和公司名称,处理公司不存在的情况
        return $site->toArray() + [
            'company_name' => $site->company?->name ?? '无关联公司',
        ];
    });

    return response()->json($formattedSites);
}

方法二:直接使用JOIN查询(一次性获取数据)

如果不想处理模型关联的对象转换,也可以直接用leftJoin来关联表,一次性查询出所有需要的数据:

use App\Models\Site;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Response;

public function getSitesWithCompany()
{
    $sites = Site::select(
            'sites.*',
            // 用COALESCE处理公司不存在的情况,返回默认值
            DB::raw('COALESCE(companies.name, "无关联公司") as company_name')
        )
        ->leftJoin('companies', 'sites.company_id', '=', 'companies.id')
        ->get();

    return response()->json($sites);
}

这种方法的好处是只执行一次SQL查询,性能更优,适合数据量较大的场景。

方法三:使用模型访问器(自动附带字段)

如果你的业务中经常需要获取站点的公司名称,可以在Site模型中定义一个访问器,让它自动出现在模型的数组/JSON输出里:

给Site模型添加访问器和$appends属性

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Site extends Model
{
    // 自动把访问器字段加入模型的数组/JSON输出
    protected $appends = ['company_name'];

    // ... 其他模型代码

    public function company(): BelongsTo
    {
        return $this->belongsTo(Company::class);
    }

    // 定义公司名称的访问器
    public function getCompanyNameAttribute()
    {
        return $this->company?->name ?? '无关联公司';
    }
}

控制器中直接获取数据

之后在控制器里就可以直接查询,不需要额外处理:

use App\Models\Site;
use Illuminate\Http\Response;

public function getSitesWithCompany()
{
    // 记得预加载关联,避免N+1查询
    $sites = Site::with('company:id,name')->get();

    return response()->json($sites);
}

这样返回的每个站点JSON对象都会自动包含company_name字段,非常省心!


内容的提问来源于stack exchange,提问作者Melisa Angelina

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:49:12