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

Laravel API:如何通过Resource获取beasiswas与mitras关联数据?

问题:Eloquent关联beasiswas与mitras表时的列重复及识别错误

我在YouTube上学了用Eloquent从数据库返回数据的教程,基础功能能正常运行,但不知道怎么关联beasiswas表的外键和mitras表的主键。在Resource文件里尝试引入表模型时,系统提示两表的「id」列名称重复;指定beasiswas.id和mitras.id区分时,又提示无法识别「beasiswas」。

我的代码

App\Http\Resources\V1\BeasiswaResource

<?php

namespace App\Http\Resources\V1;
use App\Models\Beasiswa;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class BeasiswaResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        $beas = Beasiswa::join('mitras','beasiswas.id','=','mitras.id')->get();
        
        
        return [
            'idBeasiswa'=>$beas->beasiswas.id,
            'idMitra'=>$beas->id_mitra,
            'deskripsi'=>$beas->deskripsi,
            'angkatanAwal'=>$beas->angkatan_awal,
            'angkatanAkhir'=>$beas->angkatan_akhir,
            'semMin'=>$beas->sem_min,
            'semMax'=>$beas->sem_max,
            'status'=>$beas->status
        ];
    }
}

App\Http\Controllers\Api\V1\BeasiswaController

<?php

namespace App\Http\Controllers\Api\V1;

use App\Models\Beasiswa;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreBeasiswaRequest;
use App\Http\Requests\UpdateBeasiswaRequest;
use App\Http\Resources\V1\BeasiswaResource;
use App\Http\Resources\V1\BeasiswaCollection;

class BeasiswaController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        return new BeasiswaCollection(Beasiswa::paginate());
    }
...
解决方案

你当前的写法存在几个核心问题:

  1. 在Resource的toArray方法里直接执行Beasiswa::join()->get()完全错误——Resource本身是接收已查询完成的模型实例/集合,不需要重新发起数据库查询,而且get()返回的是模型集合,不是单个模型,直接调用$beas->beasiswas.id会触发语法错误。
  2. 手动用join硬关联会导致列名冲突,Eloquent的关联模型才是处理表关联的标准方式,无需手动编写join语句。

步骤1:给Beasiswa模型定义关联关系

打开App\Models\Beasiswa,添加关联方法(假设beasiswas表的外键是id_mitra,关联mitras表的id主键):

<?php

namespace App\Models;

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

class Beasiswa extends Model
{
    // 定义与Mitra模型的关联
    public function mitra(): BelongsTo
    {
        return $this->belongsTo(Mitra::class, 'id_mitra', 'id');
    }
}

步骤2:修改BeasiswaResource

Resource直接使用当前资源的属性和关联关系,不需要重新查询数据库:

<?php

namespace App\Http\Resources\V1;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class BeasiswaResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        // Resource接收的是单个Beasiswa模型实例,直接用$this访问属性和关联
        return [
            'idBeasiswa' => $this->id, // 此处即为beasiswas表的id
            'idMitra' => $this->id_mitra,
            'deskripsi' => $this->deskripsi,
            'angkatanAwal' => $this->angkatan_awal,
            'angkatanAkhir' => $this->angkatan_akhir,
            'semMin' => $this->sem_min,
            'semMax' => $this->sem_max,
            'status' => $this->status,
            // 如果需要返回mitra的详细信息,可以添加以下代码(需先创建MitraResource)
            // 'mitra' => new MitraResource($this->whenLoaded('mitra'))
        ];
    }
}

步骤3:优化控制器,预加载关联(可选但推荐)

为了避免N+1查询问题(每个Beasiswa实例单独查询一次mitra表),在控制器里预加载关联:

public function index()
{
    // 用with预加载mitra关联
    return new BeasiswaCollection(Beasiswa::with('mitra')->paginate());
}

关于之前报错的原因

  • 你在Resource里执行Beasiswa::join()->get()得到的是模型集合,不是单个模型,所以$beas->beasiswas.id完全不符合语法,集合不存在beasiswas这个属性。
  • 手动使用join时,若两张表都有id列,查询结果中的id会被后一张表的id覆盖,需要用select指定别名(比如Beasiswa::join('mitras','beasiswas.id_mitra','=','mitras.id')->select('beasiswas.id as beasiswa_id', 'mitras.id as mitra_id', ...)->get()),但这并非Eloquent的推荐用法,使用关联模型才是更规范的实现方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:54:55