【问题标题】:Laravel Eloquent how to get all products according to category idLaravel Eloquent 如何根据类别 id 获取所有产品
【发布时间】:2020-09-08 08:12:23
【问题描述】:

用户产品控制器

class UserProductsController extends Controller
{
    public function index()
    {
        $products = Product::get();
        return view ('products')->with(compact('products'));
      
    }
      
    public function product_categories()
    {
        $categories = Category::all();
        return view ('categories')->with(compact('categories'));
      
    }
  
}

products_table

 public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('prod_name');
            $table->string('prod_brand')->nullable();
            $table->unsignedBigInteger('cat_id');
            $table->string('prod_image_path')->nullable();
            $table->timestamps();

            $table->foreign('cat_id')
            ->references('id')
            ->on('categories')
            ->onDelete('cascade');
        });
    }

categories_table

   public function up()
        {
            Schema::create('categories', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('cat_name');
                $table->string('cat_image_path')->nullable();
                $table->string('cat_description')->nullable();
                $table->timestamps();
            });
        }

产品型号

class Product extends Model
{
  

    public function category()
    {
        return $this->belongsTo('App\Category','category_id');
    }
 
    
}

类别型号

class Category extends Model
{
   public function category()
   {
       return $this->hasMany('App\Product');
   }
}

我的路线是

Route::get('/All_Products', 'UserProductsController@index')->name('All_Products');
Route::get('/product_categories', 'UserProductsController@product_categories')->name('categories');

我怎样才能获得同一类别的所有产品?因为这是我的第一个项目,所以我花更多的时间在这上面。但没有什么对我有用。谁能指导我一下?

【问题讨论】:

  • 与您的问题无关,但是您的 Product 模型上的category() 关系方法不正确,应该是$this->belongsTo('App\Category', 'cat_id'),因为您的外键列称为cat_id 而不是@987654330 @

标签: php laravel e-commerce


【解决方案1】:

假设您正确设置了您的关系(事实并非如此)

Eloquent 有几种方法:

$products = Category::findOrFail($categoryId)->products;

$products = Product::where('category_id', $categoryId)->get();

$products = Product::whereHas('category', function ($query) use ($categoryId) {
    $q->where('id', $categoryId);
})->get();

列举几个。

Laravel 7.x Docs - Eloquent - Retrieving Single Models / AggregatesfindOrFail

Laravel 7.x Docs - Eloquent - Relationships - Relationship Methods vs Dynamic Properties

Laravel 7.x Docs - Eloquent - Relationships - Querying the Existence of RelationshipswhereHas

【讨论】:

  • 这些都是可靠的选择。如果您已经有可用的类别模型,那么第一个选项应该是您的首选。如果您不需要访问 Category 模型的任何属性(不需要表连接),则第二个选项非常有用。第三种选择是一种不太常见的方法,但它会 100% 起作用。
  • 虽然这些选项在理论上都有效,但要使其在 OP 的情况下工作,第二个选项应该是 cat_id 而不是 category_id,第三个选项将不起作用,因为关系设置不正确,又是因为category_id => cat_id
【解决方案2】:

首先,你没有正确定义你的关系。应该是这样的:

class Product extends Model
{
    public function category()
    {
        return $this->belongsTo('App\Category');
    }
}
class Category extends Model
{
   public function products()
   {
       return $this->hasMany('App\Product');
   }
}

然后在您的产品迁移文件中,cat_id 应重命名为 category_id。这样,您无需在关系上指定外键。

我假设您想列出属于特定类别的所有产品。您可以使用路由模型绑定轻松地做到这一点。在这种情况下,您的路线应该类似于:

Route::get('categories/{category:id}/products', [CategoryController::class, 'products']);

然后在你的控制器中:

use App\Category;

class CategoryController extends Controller
{
    public function products(Category $category)
    {
        $category->load('products');

        return view('products')->withCategory($category);
    } 
}

您可以像这样访问刀片视图中的产品列表:$category->products

【讨论】:

【解决方案3】:

您需要对您的Category 模型进行调整,因为Category 有许多Products。就目前而言,关系的命名并不能反映这一点

class Category extends Model
{
   public function products()
   {
       return $this->hasMany('App\Product');
   }
}

然后您可以像这样通过Category 模型访问产品。

$categories = Category::with('products')->all();

$categories->each(function($category) {
    $products = $category->products;
    
    // Dump & Die a collection of products
    dd($products);
});

注意:我已经使用with() 方法急切地加载了关系,这只是为了防止n+1 查询。有关急切和延迟加载的更多信息,请参阅文档。

【讨论】:

  • 它的名称不正确。它应该是 products 而不是 category
【解决方案4】:

你可以这样做,

$products = product::with('categories')->get();
foreach($products as $product)
{
    foreach($product->categories as $category)
    {
        echo $category->name;
    }
}
$categories = Category::with('products')->get();

$category = Category::with('products')->find($category_id);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 2021-06-17
    • 2016-01-09
    相关资源
    最近更新 更多