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

Laravel 9 多对多关系:如何展示用户选中的游戏?

问题描述

我有Users、Videogames和用户游戏关联表三张数据表,想要实现展示用户选中的游戏的功能,但当前效果不符合预期。以下是相关代码,请帮忙解决:


控制器代码

public function users()
{
    $videogamesBuilder = VideoGames::with(['plataforma', 'generos', 'categoria', 'numJugadores', 'users']);
    $users = DB::table('users')->select('user_id', 'nombre', 'email','rol_usuario')->get();
    $videogames = $videogamesBuilder->paginate(4)->withQueryString();
    return view('admin.videojuegos.users', [
    'videogames' => $videogames,
    'users' => $users,
]);
}

User模型代码

class User extends User
{
   use HasApiTokens, Notifiable;
   protected $table = 'users';
   protected $primaryKey = 'user_id';
   protected $fillable = [ 'email', 'nombre', 'password', 'rol_usuario'];
   protected $hidden = ['password', 'remember_token'];
   public const VALIDATE_RULES = [
    'email' => 'required',
    'nombre' => 'required|min:5',
    'password' => 'required|numeric|min:0',
    'rol_usuario' => 'required',
];
}

Videogame表迁移文件

class CreateVideojuegosTable extends Migration
{
public function up()
{
     Schema::create('videogames', function (Blueprint $table) {
     $table->id('videogame_id');
     $table->string('titulo', 300);
     $table->text('subtitulo');
     $table->timestamps();
});
}

public function down()
{
    Schema::dropIfExists('videogames');
}
}

Users表迁移文件

return new class extends Migration
{

public function up()
{
Schema::create('users', function (Blueprint $table) {
   $table->id('user_id');
   $table->string('email')->unique();
   $table->string('nombre');
   $table->string('password');
   $table->string('rol_usuario');
   $table->rememberToken();
   $table->timestamps();
});
}

public function down()
{
   Schema::dropIfExists('users');
}
};

用户选中游戏关联表迁移文件

return new class extends Migration
{

    public function up()
    {
        Schema::create('videojuegos_tienen_usuarios', function (Blueprint $table) {
        $table->foreignId('videogames_id')->constrained('videogames', 'videogames_id');
        $table->unsignedBigInteger('user_id');
        $table->foreign('user_id')->references('user_id')->on('users');
        $table->primary(['videogames_id', 'user_id']);

        $table->timestamps();
    });
}

public function down()
{
   Schema::dropIfExists('videojuegos_tienen_usuarios');
}
};

关联表数据填充文件

class VideojuegosTienenUsuariosSeeder extends Seeder
{

public function run()
{
\DB::table('videojuegos_tienen_usuarios')->insert([
[
'videojgame_id' => 1,
'user_id' => 1,
'created_at' => now(),
'updated_at' => now(),
],
[
'videojgame_id' => 2,
'user_id' => 1,
'created_at' => now(),
'updated_at' => now(),
],
[
'videojgame_id' => 2,
'user_id' => 2,
'created_at' => now(),
'updated_at' => now(),
],
[
'videojgame_id' => 2,
'user_id' => 3,
'created_at' => now(),
'updated_at' => now(),
],
[
'videojgame_id' => 3,
'user_id' => 1,
'created_at' => now(),
'updated_at' => now(),
]
]);
}
}

视图代码

<table class="table table-bordered table-striped">
        <thead>
            <tr>
                <th>ID</th>
                <th>Nombre de usuario</th>
                <th>Email Usuario</th>
                <th>Rol del Usuario</th>
            </tr>
        </thead>
        <tbody>
        @foreach($users as $user)
            <tr>
                <td>{{ $user->user_id }}</td>
                <td>{{ $user->nombre }}</td>
                <td>{{ $user->email }}</td>
                <td>{{ $user->rol_usuario }}</td>
        @endforeach
            </tr>
        </tbody>
    </table>

问题分析与修复方案

1. 模型关联缺失

当前User模型和VideoGames模型未定义多对多关联,无法正确获取用户选中的游戏。

修复User模型:

class User extends Authenticatable // 修正继承类,避免递归继承
{
   use HasApiTokens, Notifiable;
   protected $table = 'users';
   protected $primaryKey = 'user_id';
   protected $fillable = [ 'email', 'nombre', 'password', 'rol_usuario'];
   protected $hidden = ['password', 'remember_token'];
   public const VALIDATE_RULES = [
    'email' => 'required',
    'nombre' => 'required|min:5',
    'password' => 'required|numeric|min:0',
    'rol_usuario' => 'required',
];

// 新增多对多关联
public function videogames()
{
    return $this->belongsToMany(VideoGames::class, 'videojuegos_tienen_usuarios', 'user_id', 'videogames_id');
}
}

补充VideoGames模型定义:

class VideoGames extends Model
{
    protected $table = 'videogames';
    protected $primaryKey = 'videogame_id';
    protected $fillable = ['titulo', 'subtitulo'];

    // 新增多对多关联
    public function users()
    {
        return $this->belongsToMany(User::class, 'videojuegos_tienen_usuarios', 'videogames_id', 'user_id');
    }

    // 保留原有plataforma、generos等关联定义
}

2. Seeder字段错误

Seeder中使用videojgame_id,但关联表实际字段为videogames_id,导致数据无法正确插入:

修复Seeder:

class VideojuegosTienenUsuariosSeeder extends Seeder
{

public function run()
{
\DB::table('videojuegos_tienen_usuarios')->insert([
[
'videogames_id' => 1, // 修正字段名
'user_id' => 1,
'created_at' => now(),
'updated_at' => now(),
],
[
'videogames_id' => 2, // 修正字段名
'user_id' => 1,
'created_at' => now(),
'updated_at' => now(),
],
[
'videogames_id' => 2, // 修正字段名
'user_id' => 2,
'created_at' => now(),
'updated_at' => now(),
],
[
'videogames_id' => 2, // 修正字段名
'user_id' => 3,
'created_at' => now(),
'updated_at' => now(),
],
[
'videogames_id' => 3, // 修正字段名
'user_id' => 1,
'created_at' => now(),
'updated_at' => now(),
]
]);
}
}

3. 控制器数据查询优化

当前用DB门面查询用户,无法直接通过模型关联获取游戏,改为使用User模型预加载关联:

修复控制器:

public function users()
{
    // 预加载用户关联的游戏,避免N+1查询
    $users = User::with('videogames')->select('user_id', 'nombre', 'email','rol_usuario')->get();
    return view('admin.videojuegos.users', [
        'users' => $users,
    ]);
}

4. 视图未展示用户选中的游戏

当前视图仅展示用户基本信息,需添加游戏列:

修复视图:

<table class="table table-bordered table-striped">
    <thead>
        <tr>
            <th>ID</th>
            <th>Nombre de usuario</th>
            <th>Email Usuario</th>
            <th>Rol del Usuario</th>
            <th>Juegos Seleccionados</th> <!-- 新增列 -->
        </tr>
    </thead>
    <tbody>
        @foreach($users as $user)
            <tr>
                <td>{{ $user->user_id }}</td>
                <td>{{ $user->nombre }}</td>
                <td>{{ $user->email }}</td>
                <td>{{ $user->rol_usuario }}</td>
                <td>
                    @foreach($user->videogames as $game)
                        <span>{{ $game->titulo }}</span>@if(!$loop->last), @endif
                    @endforeach
                </td>
            </tr>
        @endforeach
    </tbody>
</table>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:30:16