web-dev-qa-db-ja.com

Laravelでカテゴリのネストされたリストを作成するにはどうすればよいですか?

Laravelでカテゴリのネストされたリストを作成するにはどうすればよいですか?

私はこのようなものを作りたいです:

  • --- Php
  • ------ Laravel
  • - - - - - バージョン
  • ------------ V 5.7
  • --- Python
  • ------ Django
  • --- ルビー
  • ........。

カテゴリテーブルのフィールドは次のとおりです。

id | name | parent_id

深さなどの別の列を追加する必要がある場合は、教えてください。

私はこの次のコードを使用していますが、それは最善の解決策ではないと思います。その上、私はこの関数を私の見解に渡すことができません。

function rec($id)
{
     $model = Category::find($id);
     foreach ($model->children as $chield) rec($chield->id);
     return $model->all();
}

function main () {
    $models = Category::whereNull('parent_id')->get();
    foreach ($models as $parent) return rec($parent->id);
}
9
X 47 48 - IR

自己参照モデルを作成できます。

class Category extends Model {

    public function parent()
    {
        return $this->belongsTo('Category', 'parent_id');
    }

    public function children()
    {
        return $this->hasMany('Category', 'parent_id');
    }
}

再帰的な関係を作ります:

// recursive, loads all descendants
public function childrenRecursive()
{
   return $this->children()->with('childrenRecursive');
}

そして、すべての子供たちと一緒に親を得るには:

$categories = Category::with('childrenRecursive')->whereNull('parent')->get();

最後に、子がnullになるまで、子を反復処理する必要があります。注意しないと、これには間違いなくパフォーマンスの問題が発生する可能性があります。これがかなり小さいデータセットであり、そのままにしておく予定の場合は、問題にはなりません。これが増え続けるリストになる場合は、root_parent_idなどをクエリして、ツリーを手動でアセンブルするのが理にかなっているかもしれません。

7
Alex Harris

誰かがより良い答えを必要としているなら、私の答えを調べてください、私がそのような問題に直面したとき、それは私を助けました。

   class Category extends Model {

     private $descendants = [];

     public function children()
        {
            return $this->subcategories()->with('children');
        }

     public function hasChildren(){
            if($this->children->count()){
                return true;
            }

            return false;
        }

     public function findDescendants(Category $category){
            $this->descendants[] = $category->id;

            if($category->hasChildren()){
                foreach($category->children as $child){
                    $this->findDescendants($child);
                }
            }
        }

      public function getDescendants(Category $category){
            $this->findDescendants($category);
            return $this->descendants;
        }
 }

そして、コントローラーでこれをテストするだけです。

$category = Category::find(1);
$category_ids = $category->getDescendants($category);

これにより、id = 1であるカテゴリのすべての子孫の配列にIDが生成されます。その後:

$products = Product::whereIn('category_id',$category_ids)->get();

どういたしまして=)

1
tokkerbaz

あなたはこのようにこの問題を解決することができます:

class Category extends Model
{
    public function categories()
    {
       return $this->hasMany(Category::class);
    }

    public function childrenCategories()
    {
       return $this->hasMany(Category::class)->with('categories');
    }

}

このような子供を持つカテゴリを取得します:

Category::whereNull('category_id')
    ->with('childrenCategories')
    ->get();

注意:parent_id列の名前をcategory_idに変更するだけです

0
Amir Kaftari

私は問題を解決しました:

見る:

    $traverse = function ($categories) use (&$traverse) {
        foreach ($categories as $category) {
            $traverse($cat->Children);
        }
    };
    $traverse(array ($category));

唯一の問題は、コントローラーで情報を計算できないことです

モデル:

public function Children()
{
    return $this->hasMany($this, 'parent');
}

public function Parent()
{
    return $this->hasOne($this,'id','parent');
}
0
X4748

この領域で何かを探している私は、子供の深度レベルを取得するための機能を共有したいと思いました。

    function getDepth($category, $level = 0) {
    if ($category->parent_id>0) {
        if ($category->parent) {
                $level++;
                return $this->getDepth($category->parent, $level);
            }
        }
       return $level;
    }

多分それは誰かを助けるでしょう!乾杯!

0
nickRO87