سلام . من یه جدول category دارم که یه فیلد parent_id هم گذاشتم و زیرمنوها رو مشخص کردم و از لحاظ نمایش منو مشکلی ندارم الان ...
تو جدول محصولات هم یه cat_id گذاشتم و دسته مربوط به هر محصول رو مشخص کردم . مثلا سامسونگ یا سونی یا ال جی یا ....
ولی مشکلم اینه میخوام وقتی کاربر روی مثلا موبایل کلیک میکنه همه اون محصولاتی که دسته بندیشون سامسونگ / سونی / ال جی / اپل هم هست نشون داده بشه!
هر کاری میکنم نمیشه . میشه راهنمایی کنید اعصابمو بهم ریخته
http://uupload.ir/files/t7f1_1.png
اگه دسته بندی ها حداکثر تا دو سطح هست (مثالا زیر دسته ای برای سونی نباید داشته باشی) با دو تا کوئری مشکلت حل میشه . اول id تمای زیر دسته های مثلا موبایل رو پیدا میکنی و در کوئری دوم با دستور in در sql تمام محصولات را از جدول محصولات انتخاب می کنی . و تمام
البته یه روش یکم سخت هم هست که اگه بتونی با اون روش اطلاعات دسته ها را در جدول زخیره کنی دیگه این محدودیت دو سطحی را هم نداری و میتوانی تا بی نهایت دسته و زیر دسته و زیر زیر دسته و... داشته باشی . این لینک را بخون http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
من این روش رو توی لاراول پیاده کردم خیلی راحت شدم. اگی با لاراول کار میکنی بگو تا کد هاشو بزارم برات
سلام یک observer با محتوای زیر بساز
<?php
namespace AppObservers;
use IlluminateDatabaseEloquentModel;
class TreeObserver
{
public function saving(Model $model)
{
$class = get_class($model);
if (empty($model->tree_parent)) {
$model->tree_depth = 1;
$model->tree_left = 1;
$model->tree_right = 2;
$model->tree_parent = 0;
} else {
$parent = $class::where(["id" => $model->tree_parent])->first();
$model->tree_depth = $parent->tree_depth + 1;
$model->tree_left = $parent->tree_left + 1;
$model->tree_right = $parent->tree_left + 2;
}
}
public function created(Model $model)
{
$this->updateOther($model);
}
public function updated(Model $model)
{
$this->refreshTree($model);
}
private function updateOther(Model $model, $totalChild = 1)
{
$class = get_class($model);
$class::where("tree_right", ">=", $model->tree_left)->where('id', '!=', $model->id)->increment('tree_right', $totalChild * 2);
$class::where("tree_left", ">=", $model->tree_left)->where('id', '!=', $model->id)->increment('tree_left', $totalChild * 2);
}
public function refreshTree($model)
{
$list = $model::query()
->orderBy("tree_depth")
->get(["id", "tree_parent", "tree_depth"]);
$pointers = [];
$listTree = [];
foreach ($list as $c) {
if ($c->tree_parent == 0) {
$cat = [
"id" => $c->id,
"child" => []
];
$pointers[$c->id] =& $cat['child'];
$listTree[] = $cat;
} else {
$cat = [
"id" => $c->id,
"child" => []
];
$pointers[$c->id] =& $cat['child'];
$pointers[$c->tree_parent][] = $cat;
}
}
$i = 1;
$list = $this->childTree($listTree, $i, $model);
}
public function childTree($list, $i, $model)
{
foreach ($list as $item) {
$item['tree_left'] = $i;
$i++;
$r = $this->childTree($item['child'], $i, $model);
$item['child'] = $r[0];
$i = $r[1];
$item['tree_right'] = $i;
$model::query()
->where("id", '=', $item['id'])
->update([
'tree_left' => $item['tree_left'],
'tree_right' => $item['tree_right'],
]);
$i++;
}
return [$list, $i];
}
}
در AppServiceProvider هم باید observer را ثبت کنی
به مایگریشن دسته ها هم فیلد های زیر رو اضافه کن
$table->unsignedInteger('tree_parent')->default(0);
$table->unsignedInteger('tree_left')->nullable();
$table->unsignedInteger('tree_right')->nullable();
$table->unsignedInteger('tree_depth')->nullable();
برای ثبت یا ویرایش دسته فقط نیازه که tree_parent که همون id دسته بندی parent هست را ثبت کنی بقیه مواردخودکار توسط observer ایجاد می شوند .
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟