1452 — Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не работает в Laravel 10 — SQLSTATE [23000]: нарушение ограничения целостности

Привет, я столкнулся с проблемой сохранения записи в таблице категорий, имеющей собственный идентификатор (первичный ключ) в качестве parent_id в качестве внешнего ключа (подробности см. в миграции), когда я сохраняю данные, отображается следующая ошибка.

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`laravel`.`categories`, CONSTRAINT `categories_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `categories` (`id`))

Мой код миграции

Schema::create('categories', function (Blueprint $table) {
            $table->id();
            //$table->integer('parent_id')->default(0);
            $table->bigInteger('parent_id')->nullable()->unsigned()->default(0);
            $table->string('name');
            $table->string('slug');
            $table->text('description')->nullable();
            $table->string('image');
            $table->string('meta_title')->nullable();
            $table->string('meta_description')->nullable();
            $table->string('meta_keywords')->nullable();
            $table->integer('navbar_status')->nullable()->default(0);
            $table->integer('is_active')->nullable()->default(0);
            $table->timestamps();
            //$table->foreign('parent_id')->references('id')->on('categories');
        });
        Schema::table('categories', function (Blueprint $table) {
            $table->foreign('parent_id')->references('id')->on('categories');
        });

Мой код контроллера для хранения записи

public function store(CategoryFormRequest $request){

        $data = $request->validated();

        $category = new Category();

        $slug = Str::of($data['name'])->slug('-');
        

        if ($request->hasFile('image')) {
            $file = $request->file('image');
            $category_image = date('ymd')."-".time()."c.".$file->getClientOriginalExtension();
            $file->move('uploads/category/', $category_image);
        }

        if ($request->hasFile('banner_image')){
            $bnr_file = $request->file('banner_image');
            $cat_banner_image = date('ymd')."-".time().'b.'.$bnr_file->getClientOriginalExtension();
            $bnr_file->move('uploads/category/',$cat_banner_image);
        }

        $category->parent_id        = $data['parent_id'];
        $category->name             = $data['name'];
        $category->slug             = $slug;
        $category->description      = $data['description'];

        $category->image            = $category_image;
        $category->banner_image     = $cat_banner_image;

        $category->meta_title       = $data['meta_title'];
        $category->meta_description = $data['meta_description'];
        $category->meta_keywords    = $data['meta_keywords'];
        $category->navbar_status    = $request->navbar_status == true ? 1 : 0;
        $category->is_active        = $request->is_active == true ? 1 : 0;
        $category->is_featured      = $request->is_featured == true ? 1 : 0;
        

        $category->created_by       = Auth::user()->id;

        $category->save();

        return redirect()->route('category-create')->with('success', 'Category Added Successfully');
    }
default(0) неправильно, так нельзя. Вы можете добавить одну строку $table->foreignId('parent_id')->constrained();
STA 13.05.2023 08:46

@тф. Спасибо, вы хотите сказать, что я должен заменить следующую строку из миграции $table->bigInteger('parent_id')->nullable()->unsigned()->def‌​ault(0); с вашим данным предложением?

Umair Mehmood 13.05.2023 09:02
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
2
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

в вашем файле миграции используйте это вместо вашего

Schema::create('categories', function (Blueprint $table) {
            $table->id();

           $table->foreignId('parent_id')
                ->nullable()
                ->references('id')
                ->on('categories');

            $table->string('name');
            $table->string('slug');
            $table->text('description')->nullable();
            $table->string('image');
            $table->string('meta_title')->nullable();
            $table->string('meta_description')->nullable();
            $table->string('meta_keywords')->nullable();
            $table->integer('navbar_status')->nullable()->default(0);
            $table->boolean('is_active')->default(false);

            $table->foreignId('created_by')
                ->references('id')
                ->on('users');

            $table->foreignId('updated_by')
                ->nullable()
                ->references('id')
                ->on('users');
            $table->timestamps();
});

когда вы внедряете класс FormRequest в качестве зависимости в Laravel, Laravel автоматически проверяет request для вас, поэтому вам не нужно снова проверять его в своем контроллере. В своем коде используйте это: не забудьте, если $request->all() не подходит, используйте $request->only(['name', 'description', ...]). Попробуйте dd($request->all()) и dd($request->only(['name', 'description', ...]) просмотреть содержимое, чтобы убедиться, что все в порядке.

public function store(CategoryFormRequest $request, Category $category){
        
        if ($request->hasFile('image')) {
            $file = $request->file('image');
            $category_image = date('ymd')."-".time()."c.".$file->getClientOriginalExtension();
            $file->move('uploads/category/', $category_image);
        }

        if ($request->hasFile('banner_image')){
            $bnr_file = $request->file('banner_image');
            $cat_banner_image = date('ymd')."-".time().'b.'.$bnr_file->getClientOriginalExtension();
            $bnr_file->move('uploads/category/',$cat_banner_image);
        }

        Category::create($request->all());

        return redirect()->route('category-create')->with('success', 'Category Added Successfully');
    }

Следующим шагом является создание слушателя для вашей модели, который вызывает наблюдателя в команде artisan php artisan make:observer CategoryObserver

namespace App\Observers;

use App\Models\Category;

class CategoryObserver
{
    public function creating(Category $category)
    {
        $category->created_by = auth()->id();
        $category->slug = Str::of($category->name)->slug('-');
    }
    
    public function updating (Category $category)
    {
        $category->updated_by = auth()->id();
    }
}

и теперь вам нужно зарегистрировать своего наблюдателя в своей модели, открыть App\Providers\EventServiceProvider и добавить эту строку кода в метод boot следующим образом:


namespace App\Providers;


use App\Models\Category;
use App\Observers\CategoryObserver;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;


class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
    ];

    public function boot(): void
    {
        Category::observe(CategoryObserver::class); // add this line of code
    }

    public function shouldDiscoverEvents(): bool
    {
        return false;
    }
}

Спасибо за ваш ценный подробный ответ, ценю ваши усилия. позвольте мне попробовать ваши данные предложения ...

Umair Mehmood 13.05.2023 12:27

Другие вопросы по теме