英文:
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 无法添加或更新子行:外键约束失败(laravel
,categories
表,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;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论