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

Laravel关联3张表实现借阅视图报错排查与解决

图书借阅关联数据展示问题排查与实现

问题背景

数据库包含三张表:

  • users:id、name(string)、email(string)、username(string)、password(string)
  • bukus:id、nama_buku(string)、cover(string)、author(string)、barcode(string)
  • bukus_users(多对多中间表):id、bukus_id(bigint)、users_id(bigint)、tgl_pinjam(datetime)、tgl_tenggat(datetime)、status(boolean)

需求:在视图中展示借阅数据,将bukus_id替换为图书名称nama_buku,users_id替换为用户的name/email/username,生成包含序号、用户信息、图书名称、借阅日期、到期日期、状态的表格。

遇到的错误:

  1. SQL错误:SQLSTATE[42S22]: Column not found: 1054 Unknown column 'bukus.bukus_users_id' in 'field list'
  2. 属性读取错误:Attempt to read property "user" on int

错误原因分析

  1. 第一个SQL错误:Eloquent多对多关联定义时未指定正确外键,Laravel默认按模型名生成外键(如bukus_users_id),但实际中间表字段为bukus_id和users_id,导致关联查询找错字段。
  2. 第二个属性错误:直接将users_id这类int类型的字段值当作关联对象调用(如$item->user),但字段值并非关联模型实例。

修正后的代码实现

1. Eloquent模型定义

User.php(用户模型)

namespace App\Models;

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

class User extends Model
{
    protected $table = 'users';

    // 与图书的多对多关联
    public function bukues(): BelongsToMany
    {
        return $this->belongsToMany(Buku::class, 'bukus_users', 'users_id', 'bukus_id')
            ->withPivot('tgl_pinjam', 'tgl_tenggat', 'status', 'id'); // 包含中间表额外字段
    }
}

Buku.php(图书模型)

namespace App\Models;

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

class Buku extends Model
{
    protected $table = 'bukus';
    protected $primaryKey = 'id';

    // 与用户的多对多关联
    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'bukus_users', 'bukus_id', 'users_id')
            ->withPivot('tgl_pinjam', 'tgl_tenggat', 'status', 'id');
    }
}

BukuUser.php(中间表模型,用于直接操作借阅记录)

namespace App\Models;

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

class BukuUser extends Model
{
    protected $table = 'bukus_users';
    protected $fillable = ['bukus_id', 'users_id', 'tgl_pinjam', 'tgl_tenggat', 'status'];

    // 关联用户模型
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'users_id');
    }

    // 关联图书模型
    public function buku(): BelongsTo
    {
        return $this->belongsTo(Buku::class, 'bukus_id');
    }
}

2. PinjamController控制器代码

namespace App\Http\Controllers;

use App\Models\BukuUser;
use Illuminate\Http\Request;

class PinjamController extends Controller
{
    public function index()
    {
        // 预加载用户和图书关联,避免N+1查询问题
        $pinjams = BukuUser::with(['user', 'buku'])->get();
        return view('admin.pinjam.index', compact('pinjams'));
    }
}

3. 视图文件(admin/pinjam/index.blade.php)

<div class="container">
    <h1>Daftar Peminjaman Buku</h1>
    <table class="table table-bordered">
        <thead>
            <tr>
                <th>No</th>
                <th>Informasi Pengguna</th>
                <th>Nama Buku</th>
                <th>Tanggal Pinjam</th>
                <th>Tanggal Tenggat</th>
                <th>Status</th>
            </tr>
        </thead>
        <tbody>
            @foreach($pinjams as $item)
            <tr>
                <td>{{ $loop->iteration }}</td>
                <td>
                    Nama: {{ $item->user->name }}<br>
                    Email: {{ $item->user->email }}<br>
                    Username: {{ $item->user->username }}
                </td>
                <td>{{ $item->buku->nama_buku }}</td>
                <td>{{ $item->tgl_pinjam->format('d-m-Y H:i') }}</td>
                <td>{{ $item->tgl_tenggat->format('d-m-Y H:i') }}</td>
                <td>
                    @if($item->status)
                        <span class="badge bg-success">Sudah Kembali</span>
                    @else
                        <span class="badge bg-danger">Belum Kembali</span>
                    @endif
                </td>
            </tr>
            @endforeach
        </tbody>
    </table>
</div>

关键说明

  • 中间表模型BukuUser使用belongsTo关联用户和图书,而非多对多的belongsToMany,可直接查询中间表所有字段并关联对应模型。
  • 控制器中用with(['user', 'buku'])预加载关联,避免循环查询时产生大量SQL请求。
  • 视图中通过$item->user和$item->buku访问关联模型属性,而非直接操作users_id或bukus_id字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:42:17