[英]Getting sub category info in parent category in laravel
I have multi level category where structure is like: 我有多层结构,其中的结构是:
Parent
- first child
-- second child
- another child
What I want to do is, getting products in all child levels in Parent Page
so that I can have all products of parent, first child, second child, another child
inside Parent
. 我想要做的是,让产品在所有子级别Parent Page
,这样我可以有所有产品parent, first child, second child, another child
里面Parent
。
What I have so far, currently I can get products of Parent, first child & another child
but I'm not able to get products of my second child
. 到目前为止,我目前能获得Parent, first child & another child
产品,但我无法获得second child
。
public function totalcategoriessubs($catslug) {
$category = Category::where('slug','=',$catslug)->with('childs')->first();
//testing this
// $products = Product::whereHas('category', function($q) use ($catslug,$category)
// {
// $q->where(function($q) use ($catslug,$category) {
// $q->where('slug',$catslug)->orWhere('category_id',$category->id);
// });
// })->orderBy('created_at', 'DESC')->paginate(10);
$products = Product::whereHas('category', function($q) use ($catslug, $category) {
$q->where(function($q) use ($catslug,$category) {
$q->where('slug',$catslug) //works
->WhereHas('childs') //works
->WhereHas('childs.childs') //not working
->orWhere('category_id',$category->id); //works
});
})->orderBy('created_at', 'DESC')->paginate(10);
//end testing
return view('front.categoriessubs', compact('products', 'category'));
}
Product model
public function category(){
return $this->belongsTo(Category::class);
}
Category model
public function categories()
{
return $this->hasMany(Category::class);
}
public function childs() {
return $this->hasMany(Category::class,'category_id','id') ;
}
public function parent()
{
return $this->belongsTo(Category::class,'category_id');
}
public function isParent()
{
return !$this->category_id ? true : false; // if category_id is null => is a Parent Category
}
public function products(){
return $this->hasMany(Product::class);
}
any idea? 任何想法?
You can get the nested childs with simple trick. 您可以通过简单的技巧获得嵌套的子级。
only use protected $appends = ['childs', 'products'];
仅使用protected $appends = ['childs', 'products'];
in Model. 在模型中。
In Category.php Model 在Category.php模型中
protected appends = ['childs'];
public function categories()
{
return $this->hasMany(Category::class);
}
public function childs() {
return $this->hasMany(Category::class,'category_id','id') ;
}
public function parent()
{
return $this->belongsTo(Category::class,'category_id');
}
public function isParent()
{
return !$this->category_id ? true : false; // if category_id is null => is a Parent Category
}
public function products(){
return $this->hasMany(Product::class);
}
Now You can get the Childs using 现在您可以使用
Category::with('childs')->get();
Hope this helps. 希望这可以帮助。
Controller 调节器
<?php
namespace App\Http\Controllers;
use App\Models\Category;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* @var Category
*/
protected $category;
/**
* @var \Illuminate\Database\Eloquent\Builder
*/
protected $query;
/**
* Controller constructor.
* @param Category $category
*/
public function __construct(Category $category)
{
$this->category = $category;
$this->query = $this->category->newQuery();
}
public function home()
{
print_r($this->getAncestorCategoriesE1(2, 3)->toArray());
print_r($this->getSubCategoriesE2(null, 7)->toArray());
print_r($this->getSubCategoriesE2(1, 7)->toArray());
print_r($this->getSubCategoriesE1(null, 8)->toArray());
print_r($this->getSubCategoriesE1(1, 8)->toArray());
}
/**
* Easy method but select all
*
* @param $categoryId
* @param int $depth
* @return \Illuminate\Database\Eloquent\Collection|string|static[]
*/
public function getAncestorCategoriesE1($categoryId, $depth = 1)
{
if (!is_numeric($depth) || $depth < 1) {
return 'INvalid depth parameter';
}
$parents = [];
for ($i = 0; $i < $depth; $i++) {
$parents[] = 'parent';
}
$rel = implode('.', $parents);
return $this->category->with($rel)->find($categoryId);
}
/**
* Easy method but select all
*
* @param null $categoryId
* @param int $depth
* @return \Illuminate\Database\Eloquent\Collection|string|static[]
*/
public function getSubCategoriesE1($categoryId = null, $depth = 1) {
if (!is_numeric($depth) || $depth < 1) {
return 'INvalid depth parameter';
}
$children = [];
for ($i = 0; $i < $depth; $i++) {
$children[] = 'children';
}
$rel = implode('.', $children);
$this->addCategoryCondition($categoryId);
return $this->category->with($rel)->get();
}
/**
* @param null $categoryId
* @param int $depth
* @return \Illuminate\Database\Eloquent\Collection|static[]
*/
public function getSubCategoriesE2($categoryId = null, $depth = 4)
{
$this->addCategoryCondition($categoryId);
$this->pushSelectInQuery($this->query);
$this->pushWithInQuery($this->query, $depth);
return $this->query->get();
}
/**
* @param $query
*/
public function pushSelectInQuery($query)
{
$query->select('name', 'id', 'parent_id');
}
/**
* @param $query
* @param int $depth
*/
public function pushWithInQuery($query, $depth = 1)
{
$query->with(['children' => function($query) use ($depth) {
$this->pushSelectInQuery($query);
if (1 != $depth) {
$this->pushWithInQuery($query, --$depth);
}
}]);
}
/**
* @param $categoryId
*/
public function addCategoryCondition($categoryId)
{
if (is_null($categoryId)) {
$this->query->whereNull('parent_id');
} else {
$this->query->where('parent_id', $categoryId);
}
}
}
Model 模型
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'parent_id', 'name'
];
/**
*
*/
public function children()
{
return $this->hasMany(Category::class, 'parent_id', 'id');
}
/**
*
*/
public function parent()
{
return $this->belongsTo(Category::class, 'parent_id', 'id');
}
}
In controller has DRY I fix it later!!! 在控制器中有DRY,稍后再修复!!!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.