php - 在 Laravel 5.1 中将查询生成器条件设置为模型

标签 php laravel model

首先我不得不说我试图找到解决方案,但我没有。

基本问题:

$Br = new BrandTop;
dd( $Br->limit(10)->get() ); // Will return 10 rows

$Br = new BrandTop;
$Br->limit(10);
dd( $Br->get() ); // Will return all rows.

那么,基本问题是 - 为什么?如何为模型设置一些限制,但仍然可以使用它,例如设置(或不设置)一些位置顺序取决于其他变量。

高级问题:

我想像这样使用模型:

class BrandTop extends Model
{
    public function withBrand() {
        return $this->leftJoin('brand', 'brand.id' , '=', 'brandtop.brand_id');
    }
    public function forType($type) // there is much more conditions for type
    {
        return $this->where(['type' => $type]);
    }

    // main function
    public function forSunglasses($limit = 0, $logo = false)
    {
        if ($logo)
            $this->where(['menu_logo' => 1])->orderBy('total_sales', 'desc');
        if ($limit)
            $this->limit($limit);

        return $this->forType('sunglasses')->withBrand();
        // But there goes Error, because forType() return Builder object, and it has no withBrand() method
    }
}

因此,条件要多得多,并且在单独的方法中设置所有条件要容易得多。但如何呢?

最佳答案

模型与构建器

这里需要理解的是 Model 对象和底层 Builder(查询生成器)对象之间的区别。

语句$Br = new BrandTop;将创建一个Model的新实例,并将其分配给$Br变量。接下来,$Br->limit(10) 语句将为brand_tops 表创建一个Builder 对象的新实例,并应用 10 个限制。

在第一个示例中,通过执行 $Br->limit(10)->get(),您将在 上调用 get()应用了您的限制的构建器

在第二个示例中,您的个人 $Br->limit(10) 创建新的 Builder 实例,但从未将其用于任何用途。下一个语句 $Br->get() 创建另一个没有任何约束的新 Builder 实例,因此它检索所有记录。

为了能够构建查询,您需要将 Builder 实例分配给变量,并在最终调用 get() 之前继续修改该实例。例如,要使第二个示例正常工作:

$query = BrandTop::query();
$query->limit(10);
$query->where(/*conditions*/);
dd($query->get());

查询范围

关于问题的第二部分,您可能想研究 query scopes .

class BrandTop extends Model
{
    // renamed to "JoinBrand" instead of "WithBrand", as "with" would imply
    // an eager loaded relationship vs a joined table
    public function scopeJoinBrand($query)
    {
        return $query->leftJoin('brand', 'brand.id' , '=', 'brandtop.brand_id');
    }

    // got rid of "for" prefix
    public function scopeType($query, $type)
    {
        return $query->where('type', $type);
    }

    // got rid of "for" prefix
    public function scopeSunglasses($query, $limit = 0, $logo = false)
    {
        if ($logo)
            $query->where(['menu_logo' => 1])->orderBy('total_sales', 'desc');
        if ($limit)
            $query->limit($limit);

        return $query->type('sunglasses')->joinBrand();
    }
}

使用上述模型,您的代码将类似于:

dd(BrandTop::sunglasses()->get());

// or, more verbosely:

$query = BrandTop::query();
$query->sunglasses(); // $query already an object, no need to reassign it to itself
dd($query->get());

关于php - 在 Laravel 5.1 中将查询生成器条件设置为模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34348751/

相关文章:

.net - 是否可以使用 PHP 访问 Linux 中的 COM 对象?

javascript - 有没有更动态的方式使用 php 和 javascript 调用多个 a 标签

mysql - Laravel 在两个表之间使用 eloquent 进行计数

swift - 设计域时更喜欢可选还是非可选?

mysql - Yii 查询优化 MySQL

php - 如何在php中生成并显示最小值和最大值之间的序列号

PHP函数访问数据库连接

php - Laravel:计算关系中的行数

php - 当另一个表中值为 null 时重定向到页面 laravel

c# - 用于常见操作的 C# 属性的有序列表?