2016-03-07 66 views
4

这是用于Laravel 5.2的。我定义了一个方法,我的用户模型如下:在Eloquent查询中使用Laravel模型方法

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_firstname_last,但我希望能够搜索(并排序)name而不存储它。也许存储连接的名字没什么大不了,我应该这样做,但我也试图学习。

+0

什么Laravel的版本? –

+0

呃,对不起。 5.2 – Anthony

回答

3

我同意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(); 
+0

感谢如何使用本地范围的绝佳示例。 – Anthony

3

这意味着你应该连接数据库级别的列值。这意味着你可以使用CONCATwhereRaw条款:

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

或者作为选择,如果你想选择全名作为结果的一部分,你可以在Select串联和使用having代替where到能够使用列别名:

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

不是最紧凑的解决方案,但涉及MySQL的功能的东西需要一些原始的SQL与查询生成器的工作。

+0

谢谢。这是非常丰富和有益的。使用'having'而不是某种'where'可能会导致查询返回大量的记录,对吧? – Anthony

+1

使用'having'相当于'where',除了使用聚合函数时通常使用的明显例外,它在'GROUP BY'之后执行。在我的第二个例子中,它有助于访问列别名,否则使用'where name =?'将不起作用,因为'name'是列别名。对于这个简单的示例,它不会影响查询结果,对于更复杂的查询,您应该考虑上述执行顺序。 – Bogdan

+0

我明白你的意思了,但我仍然不确定这是如何工作的。这与我的问题不再有任何关系,但在这种情况下不会“消耗”更多内存来做同样的事情,因为'where'会实时排除行,而不是事后? – Anthony

相关问题