Pivot之间的关系table hasMany turns

Relationship between Pivot table hasMany turns

我正在尝试使用下面列出的 table 创建一个游戏。 这里有一个迁移文件的示例:Laravel.io example migration sample

枢轴 table 对于加入游戏的玩家来说效果很好,我已经使用 Vue 播种了它和 return 数据,并且每个游戏都按应有的方式列出了所有玩家。

问题 是在枢轴 table game_user(称为参与者)和回合之间建立关系。不确定我的做法是否正确,但我的想法是玩家 (game_user) 玩很多回合,一对多关系。

我真的不想在主键上创建另一个主键 table 除非我必须这样做,但我似乎无法在不抛出错误的情况下连接它们。

所以这个外键是行不通的

$table->foreign(['game_id', 'game_user_id'], 'game_user_turns_foreign')->references(['game_id,user_id'])->on('game_user')->onDelete('cascade');

Laravel 在 artisan migrate 命令期间出现此错误

 php artisan migrate:fresh --seed

 Illuminate\Database\QueryException 

  SQLSTATE[42000]: Syntax error or access violation: 1239 Incorrect foreign key definition for 'game_user_turns_foreign': Key reference and table reference don't match (SQL: alter table `turns` add constraint `game_user_turns_foreign` foreign key (
`game_id`, `game_user_id`) references `game_user` (`game_id,user_id`) on delete cascade)

有人可以帮我吗?

或者建议另一种合乎逻辑的方法来解决关系。

需要知道的重要一点是,对于游戏和参与者 (game_user),回合必须具有唯一的 link。

这是tables

Tables:

  Users Table                    Games Table   
   (shortened for example)        (shortened for example)

+-------------------+            +-------------------+
| Entity: users     |            | Entity: games     |
+-------------------+            +-------------------+
| id                |            | id                |
| first_name        |            | start_time        |
| last_name         |            | end_time          |
| display_name      |            | max_no_of_players |
| email             |            | director          |
+-------------------+            | result_id         |
                                 +-------------------+
                                 
  Pivot Table referred           Turns Table                
  as participants or players     +-------------------+         
+-------------------+            | Entity: turns     |                               
| Entity: game_user |            +-------------------+                               
+-------------------+            | id                |                               
| user_id           |            | created_at        |                               
| game_id           |            | updated_at        |                               
+-------------------+            | game_id           |                               
                                 | game_user_id      |                               
                                 | merge             |                               
                                 | purchase_array    |                       
                                 | piece_played      |                       
                                 | piece_action      |                       
                                 +-------------------+                       
 

看来我在将引用 ID 创建为 unsignedBigInteger 时犯了一个错误。我以为关键字“increments”创建了unsignedBigInteger,但我错了。

所以我将所有 id 更改为 unsignedInteger 并解决了问题。

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
class CreateTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
 
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('first_name', 25);
            $table->string('last_name', 25);
            $table->string('email', 100)->unique();
            $table->string('display_name');
        });
 
        Schema::create('games', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamp('start_time')->nullable();
            $table->timestamp('end_time')->nullable();
            $table->smallInteger('max_no_of_players')->default(2);
            $table->unsignedInteger('director')->comment('id of a player who initiated the game');
            $table->unsignedInteger('result_id')->nullable()->default(NULL)->comment('at start game has no result');
        });
 
        Schema::create('game_user', function (Blueprint $table) {
            $table->integer('user_id')->unsigned();
            $table->integer('game_id')->unsigned();
 
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreign('game_id')->references('id')->on('games')->onDelete('cascade');
 
            // Make both IDs a unique key
            $table->primary(['game_id', 'user_id']);
        });
 
         Schema::create('turns', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            $table->unsignedInteger('game_id')->nullable()->default(NULL)->comment('Game id that the turn belongs to');
            $table->unsignedInteger('game_user_id')->nullable()->default(NULL)->comment('The participants unique id (game_id and user_id)');
            $table->boolean('merge')->default(false)->comment('Did a merge take place');
            $table->string('purchase_array')->comment('An array of the transaction history for this turn');
            $table->smallInteger('piece_played')->comment('An integer between 0 and 181 that represents the array node from A1 to N13 starting at 0(zero)');
            $table->smallInteger('piece_action')->nullable()->default(NULL)->comment('Action taken with piece: 1) Played 2) Replaced (could not play) 3) thrown away (dead piece)');
            
           
             // THIS FOREIGN KEY IS WHERE THE PROBLEM IS.
            $table->foreign(['game_id', 'game_user_id'], 'game_user_turns_foreign')->references(['game_id,user_id'])->on('game_user')->onDelete('cascade');
        });
}