【问题标题】:Laravel Divided Query Overwrites Previous VariableLaravel 划分查询覆盖以前的变量
【发布时间】:2021-09-12 12:05:03
【问题描述】:

我想要实现的是创建一个查询并使用多个结尾:

例如

$query = User::where('is_admin', true);

if ($query->where('badge', 'red')->exists())
{
  //do something
}

if ($query->where('badge', 'green')->exists())
{
  //do something
}

$query->get();

$query->first();

这样,每次查询完成时,$query 变量都会被覆盖,因此无法重复使用 $query

我目前的解决方案是使用clone

$query = User::where('is_admin', true);

$query1 = clone $query;
if ($query1->where('badge', 'red')->exists())
{
  //do something
}

$query2 = clone $query
if ($query2->where('badge', 'green')->exists())
{
  //do something
}

$query3 = clone $query;
$query3->get();

$query4 = clone $query;
$query4->first();

这个例子只是为了说明问题,而不是真实的 生活场景。

我猜它可以工作并且做我想做的事,只是感觉不像是 laravel 做某事的方式,相当冗长,而且随着更复杂的逻辑变得更糟。

目标是在每次完成查询时重复使用相同的变量而不覆盖它。

有人对此有更好的解决方案吗?

有没有办法以某种方式破坏$query 变量的反应性?

谢谢

【问题讨论】:

  • $query = User::where('is_admin', true)->get();

标签: php laravel eloquent


【解决方案1】:

一个优雅的选择是使用Laravel Local Query Scopes.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Scope a query to only include administrators.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeAdmins($query)
    {
        return $query->where('is_admin', true);
    }

  
}

现在,利用新创建的本地范围:

if (User::admins()->where('badge', 'red')->exists())
{
  //do something
}

if (User::admins()->where('badge', 'green')->exists())
{
  //do something
}

【讨论】:

  • 这确实是一种更优雅的方式,但我担心从长远来看它会使我的模型最终变得“肥胖”。但是你绝对是对的,laravel 的方法是为此使用智能范围。谢谢
【解决方案2】:

对于初学者来说,$query 对于获取管理员用户来说听起来不是一个好名字。

所以,让我们快速更改它,以便我们更清晰地阅读和思考

$user_admins = User::where('is_admin', true);

if ($user_admins->where('badge', 'red')->exists())
{
  //do something
} 

if ($user_admins->where('badge', 'green')->exists())
{
  //do something
}

好的,所以我们找到了管理员,让我们用 foreach 循环

来遍历他们
$user_admins = User::where('is_admin', true);

foreach($user_admins as $admin) {
    if ($admin->badge == 'green') {
         // do something
    } else if ($admin->badge == 'red') {
        // do something else
    }
}

现在,每当您更改循环内的 $admin 变量时,它都会更改该个人管理员。

也查询是“问题” eloquent 是“询问”数据库(例如:“SELECT * FROM users WHERE is_admin=true”;所以查询不参考结果

注意如果你有很多逻辑,你也可以使用 switch 语句,它看起来像这样:

$user_admins = User::where('is_admin', true);

foreach($user_admins as $admin) {
    switch($admin->badge) {
        case 'green:
            // do something
            break;
        case 'red:
            // do something else
            break;
        case 'ltblue:
        case 'blue:
            // do same things for ltblue and blue
            break;
        default: break;
}

【讨论】:

  • 感谢您的回答,我将问题编辑得更清楚。此外,您的答案缺少变量末尾的-&gt;get();,以便您可以将它与 foreach 一起使用。无论如何,不​​是问题的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-14
  • 1970-01-01
  • 2019-06-02
  • 2019-02-27
  • 1970-01-01
相关资源
最近更新 更多