插入到 shopping_lists 表时违反外键约束

问题描述 投票:0回答:1

我在使用 Laravel(使用版本 11.1.0)向 SQLite3 表中插入条目时遇到问题,特别是违反了外键约束。

我有一个使用版本 11.1.0 的 Laravel 项目,它是通过以下迁移进行设置的:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateAllTables extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        // Create users table
        Schema::create('users', function (Blueprint $table) {
            $table->string('user_id')->primary();
            $table->string('username')->notNullable();
            // Add other user-related fields as needed
            $table->timestamps();
        });

        // Create routes table
        Schema::create('routes', function (Blueprint $table) {
            $table->increments('route_id');
            $table->text('polyline_data')->nullable();
            $table->timestamps();
        });

        // Create shopping_lists table
        Schema::create('shopping_lists', function (Blueprint $table) {
            $table->increments('list_id');
            $table->integer('user_id')->notNullable();
            $table->string('name')->notNullable();
            $table->integer('route_id')->unsigned()->nullable();
            // Foreign keys
            $table->foreign('user_id')->references('user_id')->on('users');
            $table->foreign('route_id')->references('route_id')->on('routes');
            $table->timestamps();
        });

        // Create grocery_items table
        Schema::create('grocery_items', function (Blueprint $table) {
            $table->increments('item_id');
            $table->string('name')->notNullable();
            $table->integer('quantity')->nullable();
            $table->boolean('is_food')->default(false);
            $table->integer('shopping_list_id')->unsigned();
            $table->foreign('shopping_list_id')->references('list_id')->on('shopping_lists');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('grocery_items');
        Schema::dropIfExists('shopping_lists');
        Schema::dropIfExists('routes');
        Schema::dropIfExists('users');
    }
}

我已经运行了此迁移,目前正在尝试通过使用此控制器创建列表项来插入到 shopping_lists 表(此表包含购物清单的标题)中:

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\ShoppingList;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use App\Models\Route; // Import the Route model
use Illuminate\Support\Facades\Schema; // Necessary for debugging the schema



class ShoppingListController extends Controller
{
    public function index()
    {
        return response()->json(ShoppingList::all(), 200);
    }

    public function store(Request $request)
    {
        Log::info("Received shopping-lists request from IP address " . $request->ip());

        $userId = $request->user_id;

        Log::info("User ID retrieved from JWT: " . print_r($userId, true));

        // Validate the request data
        $validatedData = $request->validate([
            'name' => 'required|string',
            'route_id' => 'nullable|integer', // Validate route_id as nullable and a valid UUID
        ]);

        Log::info("Validated request: " . print_r($validatedData, true));

        // Check if user_id exists
        /*$user = DB::table('users')->where('id', $userId)->first();
        if (!$user) {
            Log::error("User ID $userId does not exist.");
            return response()->json(['error' => 'Invalid user_id'], 400);
        }*/

        // Check if route_id exists (if provided)
        if (!empty($validatedData['route_id'])) {
            $route = DB::table('routes')->where('id', $validatedData['route_id'])->first();
            if (!$route) {
                Log::error("Route ID {$validatedData['route_id']} does not exist.");
                return response()->json(['error' => 'Invalid route_id'], 400);
            }
        }

        // Generate a UUID for route_id if not provided
        if (empty($validatedData['route_id'])) {
            $validatedData['route_id'] = null;
        }

        $newEntry = [
            'user_id' => $userId,
            'name' => $validatedData['name'],
            'route_id' => $validatedData['route_id'],
        ];

        Log::info("Entering new entry into Shopping List database: " . print_r($newEntry, true));

        try {
            $shoppingList = ShoppingList::create($newEntry);
            Log::info("Created shopping list: " . $shoppingList);
        } catch (\Exception $e) {
            Log::error("Error creating shopping list: " . $e->getMessage());
            return response()->json(['error' => 'Could not create shopping list'], 500);
        }

        return response()->json($shoppingList, 201);
    }


    public function show(ShoppingList $shoppingList)
    {
        return response()->json($shoppingList, 200);
    }

    public function update(Request $request, ShoppingList $shoppingList)
    {
        $request->validate([
            'name' => 'required|string',
            'route_id' => 'nullable|exists:routes,route_id',
        ]);

        $shoppingList->update($request->all());
        return response()->json($shoppingList, 200);
    }

    public function destroy(ShoppingList $shoppingList)
    {
        $shoppingList->delete();
        return response()->json(null, 204);
    }
}

但它在日志记录中不断给我这个错误,这清楚地表明它正在为插入提供所有字段:

[2024-05-26 17:06:07] local.ERROR: Error creating shopping list: SQLSTATE[23000]: Integrity constraint violation: 19 FOREIGN KEY constraint failed (Connection: sqlite, SQL: insert into "shopping_lists" ("user_id", "name", "route_id", "updated_at", "created_at") values (113663583418864754012, first grocery list test, ?, 2024-05-26 17:06:07, 2024-05-26 17:06:07))   

我检查过,我的用户表中已经存储了一个具有此 id 值的用户,因此唯一可能导致外键问题的其他字段应该是route_id 字段。我已经浏览过其他 stackoverflow 帖子,但找不到任何解决此特定问题的方法。任何帮助将不胜感激。

laravel sqlite eloquent foreign-keys
1个回答
0
投票

在您的 user 表上,您已将 user_id 定义为字符串,而在您的 shopping_lists 表上,您已将其定义为整数。

尝试将其定义为 shopping_lists 上的字符串,方法是创建一个更改迁移 (https://laravel.com/docs/11.x/migrations#modifying-columns) 或返回并修复该迁移你有(尽管第二个选项也会删除表中已有的数据)。

更改迁移如下所示:

Schema::table('shopping_lists', function (Blueprint $table) {
    $table->string('user_id')->change();
});
© www.soinside.com 2019 - 2024. All rights reserved.