【问题标题】:Using a Laravel model method in an Eloquent query在 Eloquent 查询中使用 Laravel 模型方法
【发布时间】:2016-06-21 18:05:33
【问题描述】:

这适用于 Laravel 5.2。我的用户模型中有一个方法定义如下:

public function name()
{
    return "$this->name_first $this->name_last";
}

我正在尝试弄清楚如何将其用作查询的一部分,但由于一个明显的原因,这似乎是不可能的:数据库对该方法一无所知,这很有意义.然而,我想要实现的概念在某些情况下是有意义的,所以我试图看看是否有办法在 Eloquent 中自然地实现它。

这不起作用,但它代表了我想要完成的事情:

public function index(Request $request)
{
    $query = new User();

    if(Request::has('name')) {
        $query = $query->where('name', 'LIKE', '%' . Request::input('name') . '%');
    }

    return $query->get();
}

简而言之,数据库只知道name_first 和name_last,但我希望能够在name 上搜索(和排序)而不存储它。也许存储串联名称没什么大不了的,我应该这样做,但我也在努力学习。

【问题讨论】:

  • 什么版本的 Laravel?

标签: php laravel methods eloquent laravel-5.2


【解决方案1】:

我同意 Bogdan 的观点,名字或姓氏中有空格的问题使得查询各个列变得困难,所以这可能是要走的路。可以通过将其定义为自定义范围来增加代码重用: https://laravel.com/docs/5.2/eloquent#local-scopes

// class User
public function scopeOfFullNameLike($query, $fullName)
{
    return $query->whereRaw('CONCAT(name_first, " ", name_last) LIKE "%?%"', [$fullName]);
}
// ...
User::ofFullNameLike('john doe')->get();

【讨论】:

  • 感谢您提供了如何使用本地范围的绝佳示例。
【解决方案2】:

这意味着您应该在数据库级别连接列值。这意味着您可以使用CONCAT 和whereRaw 子句:

$query->whereRaw('CONCAT(name_first, " ", name_last) LIKE ?', ['%' . Request::input('name') . '%']);

或者,如果您希望选择全名作为结果的一部分,您可以在选择中连接并使用having 而不是where 来使用列别名:

$query->select('*', DB::raw('CONCAT(name_first, " ", name_last) as name'))
      ->having('name', 'LIKE', '%' . Request::input('name') . '%');

不是最紧凑的解决方案,但涉及 MySQL 函数的事情需要一些原始 SQL 才能与查询生成器一起使用。

【讨论】:

  • 谢谢。这是非常有用和有益的。使用having 而不是某种类型的where 可能会导致查询返回大量记录,对吧?
  • 使用having 等效于where,但值得注意的例外是它通常在使用聚合函数时使用,并且在GROUP BY 之后执行。在我的第二个示例中,它有助于访问列别名,否则使用 where name = ? 将不起作用,因为 name 是列别名。对于这个简单的例子,它不会影响查询结果,对于更复杂的查询,您应该考虑上面提到的执行顺序。
  • 我明白你的意思,但我仍然不确定它是如何工作的。这不再与我的问题有关,但 having 在这种情况下不会消耗更多 RAM 来做同样的事情,因为 where 会实时排除行而不是事后排除?
  • @Anthony 对于这种特殊情况,它们是等效的,没有明显的性能或内存消耗。实际上,不久前我做了一个简单的基准测试,以回答关于 SO 的类似问题,我发现对于具有 100 万个条目的表上的简单查询没有区别。
  • 这很有趣。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-25
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多