با سلام بنده قصد دارم منوی چند سطحی رو به این شکل ایجاد کنم،اگر بخوایم منوی چند سطحی داشته باشیم به این صورت که که یک دسته والد داشته باشیم سپس یک زیر دسته و برای زیر دسته هم یک دسته بندی دیگه باید به چه صورت عمل کنیم؟ /مثلا" دسته والد زیبایی / زیر دسته ش بشه جراحی زیبایی /زیر دسته ی جراحی زیبایی بشه جراحی صورت ....
به این شکل اول مایگریشن رو ایجاد کردم:
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->foreignId('category_id')->nullable()->constrained();
$table->string('title_fa')->unique();
$table->string('title_en')->unique();
$table->string('description')->unique();
$table->boolean('is_active')->unsigned()->nullable();
$table->string('image')->nullable();
$table->timestamps();
});
}
بعد از اون یه request ایجاد کردم
public function rules(): array
{
return [
'title_fa' => ['required','unique:categories,title_fa'],
'title_en' => ['required','unique:categories,title_en'],
'description' => ['required','unique:categories,description'],
'category_id' => ['nullable','exists:categories,id']
];
}
و به این شکل categoryController و متد store رو فراخوانی کردم
public function store(NewCategoryRequest $request): \Illuminate\Foundation\Application|\Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse|\Illuminate\Contracts\Foundation\Application
{
Category::query()->create([
'title_fa' => $request->get('title_fa'),
'title_en' => $request->get('title_en'),
'description' => $request->get('description'),
'category_id' => $request->get('category_id')
]);
return redirect('backend/categories/create');
}
و در model هم به این شکل عمل کردم:
public function parent(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Category::class,'category_id');
}
در نهایت هم اکشن رو به روت مورد نظر که تعریف کردم لینک کردم.
در مرحله اول دسته اصلی ایجاد میشه ، اما در مرحله ای که می بایست زیر دسته بندی به دسته والد نسبت داده بشه این اتفاق نمی افته و باز هم دسته مورد نظر در دسته والد قرار میگیره و catrgoty_id در دیتابیس null ثبت میشه.
در این تصویر مشاهده می کنین که برای هر قسمت از زیر منو ها بخشی طراحی شده که بصورت جداگانه دردسته های والد خودشون ثبت بشن.منتها فقط من تونستم بخش اول یعنی دسته والد رو ثبت کنم
ممنون میشم راهنمایی بفرمایید که فرم اکشن باید به چه صورت باشه و من چطوری میتونم این دسته بندی ها رو باهم لینک کنم.
سپاس
سلام، در دوره آموزشی لاراول تمام توضیحات مربوط به ساخت کتگوری های تو در تو را آموزش داده بودم اما برای پاسخ به سوال شما راه حل را مینویسم. اگر منظور سوال شما رو به درستی متوجه شده باشم باید مراحل زیر را برای ایجاد دسته بندی های تو در تو طی کنید:
۱) ابتدا جدول دیتابیس را طراحی می کنیم. برای اینکار یک ماگریشن درست کرده و سپس ستون های جدول را به صورت زیر تنظیم می کنیم:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCategoriesTable extends Migration
{
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->unsignedInteger('parent_id')->nullable();
$table->timestamps();
$table->foreign('parent_id')->references('id')->on('categories')->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('categories');
}
}
۲) مرحله بعدی که مهم ترین مرحله هست ساخت مدل و یه تعدادی رابطه Self-join هست (این روابط SQL رو به صورت کامل در دوره آموزش مقدماتی تا پیشرفته MySQL توضیح داده ام). در کل SELF_JOIN یعنی شما یک جدول را به خودش متصل می کنید:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $fillable = [
'name',
'parent_id',
];
public function parent()
{
return $this->belongsTo(Category::class, 'parent_id');
}
public function children()
{
return $this->hasMany(Category::class, 'parent_id');
}
public function descendants()
{
return $this->hasMany(Category::class, 'parent_id')->with('descendants');
}
}
در مدل بالا با استفاده از متد children و descendants می توان به تمام فرزندان یک کتگوری دسترسی پیدا کرد. یعنی مثلا شما زیبایی رو انتخاب می کنید می توانید به تمام زیر دسته های آن مثل جراحی زیبایی، زیبایی پوست و ... دسترسی داشته باشید.
مثال برای ایجاد کتگوری و کار با آن به صورت زیر هست:
use App\Models\Category;
$category = new Category();
$category->name = "Root Category";
$category->save();
سپس برای ساخت کتگوری های تو در تو داریم:
use App\Models\Category;
$parentCategory = Category::find(1); // The parent category ID
$category = new Category();
$category->name = "Child Category";
$parentCategory->children()->save($category);
و اگر چنانچه بخواهیم تمام کتگوری های زیر مجموعه مربوط به یک کتگوری را پیدا کنیم:
use App\Models\Category;
$category = Category::find(1); // The category ID
$descendants = $category->descendants;
و اگر بخواهیم دسته بندی والد (پرنت) را پیدا کنیم:
use App\Models\Category;
$category = Category::find(2); // The category ID
$parent = $category->parent;
برای فرم اکشن هم شما باید ابتدا یک دسته بندی را به همراه تمام زیر مجموعه های آن با استفاده از متد descendants در صفحه بارگذاری کنید و سپس بررسی کنید اگر parent_id خالی یا نال نبود یعنی میتواند به صورت تو در تو پیش برود و اگر خالی بود یعنی دسته بندی به پرنت یا والد خود رسیده است. در ضمن در ابتدا برای دسترسی به دسته بندی های پرنت هم کافیست که یک کوئری بنویسید که parent_id آن نال یا خالی باشد. اینطوری به تمام دسته بندی های والد ابتدا دسترسی پیدا کرده و سپس با استفاده از دستور with می توانید کل descendants ها یا فرزندان آن را لود کنید.
امیدوارم توضیحاتم به شما کمک کرده باشد.
با سلام مجدد
و سپاس فراوان از پاسخ جامع و کامل شما استاد گرامی
من هم آموزش رو دیدم و هم توضیحات شما رو عملی کردم، منتها شما در آموزش از یک select box برای نمایش همه ی دسته بندی ها استفاده کردین، منتهامن برای هر سطح از دسته بندی ها بصورت جداگانه یک فرم ایجاد کردم و می خوام برای هر سطح از دسته بندی ها دسته والد مربوط به اون سطح نمایش داده بشه و زیر مجموعه ی اون ثبت بشه.
ولی مشکلی که دارم اینه که دسته والد ایجاد میشه،بعد از اون برای سطح بعدی در فرم جداگانه دسته والد رو انتخاب میکنم ، ولی باز هم دسته بندی بعنوان والد ثبت میشه و زیر دسته ی والد نمی یاد.من اکشن فرم رو چی باید بزارم که بتونم در چندین فرم چندیدن سطح از دسته بندی رو ایجاد کنم.
طبق عکس زیر در یک فرم دسته بندی والد ایجاد شده، و در این فرم دسته والد رو فراخوانی کردم اما بعد از ثبت فرم باز هم دسته مورد نظر بعنوان دسته والد ثبت میشه.در دیتابیس بصورت دستی که اطلاعات رو درج میکنم به درستی ایجاد میشه اما وقتی از طریق فرم اقدام میکنم عملی نمیشه.
و منظور کلی توضیحاتمم مطابق عکس زیر هستش که هر سطح برای خودش میتونه بصورت جداگانه دسته ایجاد بکنه و در هر فرمی دسته والد مربوط به اون سطح نمایش داده میشه
به جمع هزاران کاربر اینستاگرامی روکسو بپیوندید.