【问题标题】:Building a dynamic query of a many-to-many relationship in Laravel 5在 Laravel 5 中构建多对多关系的动态查询
【发布时间】:2016-10-06 00:35:39
【问题描述】:

我对 Laravel Eloquent ORM 非常陌生,并且很难构建动态查询来查询某个类别的产品。

我解析请求对象并根据传递的变量返回产品。当我查询单个模型时,这很容易,但我想知道如果一个类别被传递到,如何动态构建查询。使用标准 MYSQL 和 PHP 这很容易,但我不确定在 LAravel 中是如何实现的。

这是我的代码:

产品型号:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $primaryKey = 'id',
              $table      = 'products',
              $fillable   = array('title', 'SKU', 'description', 'created_at', 'updated_at');

    public $timestamps = true;

    /**
     * Get the categories assoicated with the product
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     *
     */
    public function categories() {
        return $this->belongsToMany('App\Category')->withTimestamps();
    }
}

类别型号:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    /**
     * Returns all products related to a category
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function products() {
        return $this->belongsToMany('App\Product')->withTimestamps();
    }

}

在我的产品控制器中,我有这个函数来获取在名为“filtervars”的类中调用方法“filterProduct”的产品:

public function index(Request $request)
{
    return FilterVars::filterProduct($request->all());
}

这里是 filterProduct 方法:

public static function filterProduct($vars) {

        $query = Product::query();

        if((array_key_exists('order_by', $vars)) && (array_key_exists('order', $vars))) {
            $query = $query->orderBy($vars['order_by'], $vars['order']);
        }

        if(array_key_exists('cat', $vars)) {
            $query = $query->whereHas('categories', function($q) use ($vars){
                return $q->where('category_id', $vars['cat']);
            });
        }     

        return $query->get();

产品数据库迁移:

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function(Blueprint $table) {
            $table->increments('id');
            $table->string('title', 75);
            $table->string('SKU')->unique();
            $table->text('description')->nullable();
            $table->timestamps();
        });
    }

以及显示类别表、数据透视表和外键等结构的迁移:

class CreateCategoriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('description');
            $table->timestamps();
        });

        Schema::create('category_product', function(Blueprint $table) {
            $table->integer('product_id')->unsigned()->index();
            $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');

            $table->integer('category_id')->unsigned()->index();
            $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
            $table->timestamps();
        });
    }

我曾尝试在查询中加入“has”方法,但这似乎不起作用。谁能告诉我哪里出错了?

谢谢!

【问题讨论】:

    标签: php laravel-5 eloquent


    【解决方案1】:

    可能你需要whereHasmethod

    $query = $query->whereHas('categories', function($q) use ($vars) {
        $q->where('id', $vars['cat']);
    });
    

    编辑

    您应该在 whereHas 方法中使用 id 列,因为您将 where 条件应用于 categories 表,没有 category_id

    public static function filterProduct($vars) {
    
        $query = Product::query();
    
        if((array_key_exists('order_by', $vars)) && (array_key_exists('order', $vars))) {
            $query = $query->orderBy($vars['order_by'], $vars['order']);
        }
    
        if(array_key_exists('cat', $vars)) {
            $query = $query->whereHas('categories', function($q) use ($vars){
                $q->where('id', $vars['cat']);
            });
        }     
    
        return $query->get();
    }
    

    【讨论】:

    • 感谢您的回复。我试过了,但它没有返回任何结果,只是一个空数组。
    • 在您的代码中,您在ifreturn 之前两次调用get() 方法。尝试只调用一次。
    • 对不起,我更新了原来的问题。我只调用了一次get方法,它仍然没有返回任何东西,
    • 您的数据库架构是什么?你使用 laravel FK 命名约定吗?您的数据透视表名称是什么?列?
    • 我已经更新了主要问题,它显示了构建表格和数据透视表的迁移。这也显示了外键
    猜你喜欢
    • 1970-01-01
    • 2019-04-24
    • 2019-02-07
    • 2020-12-15
    • 1970-01-01
    • 1970-01-01
    • 2018-11-02
    • 2015-05-29
    • 1970-01-01
    相关资源
    最近更新 更多