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