1452 – Cannot add or update a child row: a foreign key constraint fails in Laravel 10 – SQLSTATE[23000]: Integrity constraint violation

huangapple go评论64阅读模式
英文:

1452 - Cannot add or update a child row: a foreign key constraint fails in Laravel 10 - SQLSTATE[23000]: Integrity constraint violation

问题

你遇到的问题是尝试将记录存储在具有自身id(主键)作为parent_id的外键的categories表中时出现了错误。当尝试保存数据时,出现以下错误:

SQLSTATE[23000]: 完整性约束违规:1452 无法添加或更新子行:外键约束失败(laravelcategories表,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');
}

请注意,外键约束错误通常是因为父表中没有对应的值导致的。你需要确保$data['parent_id'] 的值在categories表中存在,或者你可以将其设置为nullable,以允许空值。

英文:

Hi I am facing an issue to store record in categories table having its own id(Primary Key) as parent_id as foreign key (check the migration for details), when i save the data it shows following error.

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`))

My Migration Code is

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');
});

My Controller Code to Store the Record is

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');
}

答案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();
});

当你在Laravel中将FormRequest类作为依赖项注入时,Laravel将自动为你验证请求,因此你不需要在控制器中再次验证它。在你的代码中使用以下方式:

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;
use Illuminate\Support\Str;

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方法中添加以下代码:

Category::observe(CategoryObserver::class);

希望这能帮助你完成相应的任务。

英文:

in your migration file use this instead of yours

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();
});

when you are injecting a FormRequest class as dependency in Laravel, Laravel will validate the request automatically for you thus you dont need to validate it again in your controller. In your code use this: Dont forget if $request->all() is not suitable then use $request->only(['name', 'description', ...]). Try dd($request->all()) and dd($request->only(['name', 'description', ...]) to see the content to make sure every thing is fine.

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');
}

next step is to create a listener for your model which called observer in artisan command 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();
}
}

and now you have to register your observer to your model, open App\Providers\EventServiceProvider and add this line of code to the boot method like so:


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;
}
}

huangapple
  • 本文由 发表于 2023年5月13日 14:32:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76241395.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定