2016-03-07 40 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

相關問題