[英]Laravel 4 - Eloquent way to attach a where clause to a relationship when building a collection
這可能是一個騙局,但我已經拖網一段時間尋找一個正確的答案,還沒有找到一個。
因此,基本上我想要做的就是連接兩個表,並根據連接表中的字段將where條件附加到整個集合。
所以我要說我有兩張桌子:
users:
-id
-name
-email
-password
-etc
user_addresses:
-address_line1
-address_line2
-town
-city
-etc
為了論證(實現這可能不是最好的例子) - 假設用戶可以有多個地址條目。 現在,laravel / eloquent為我們提供了一種以范圍形式包裝條件的好方法,因此我們將使用其中一個來定義過濾器。
所以,如果我想讓所有用戶在smallville獲得一個地址,我可以創建一個范圍和關系,如下所示:
Users.php(型號)
class users extends Eloquent{
public function addresses(){
return $this->belongsToMany('Address');
}
public function scopeSmallvilleResidents($query){
return $query->join('user_addresses', function($join) {
$join->on('user.id', '=', 'user_addresses.user_id');
})->where('user_addresses.town', '=', 'Smallville');
}
}
這可行,但它有點難看,它會弄亂我的雄辯對象,因為我不再擁有包含用戶地址的良好動態屬性,所有內容都只是塞進用戶對象中。
我已經嘗試了其他各種方法來實現這一點,例如在關系上使用閉包看起來很有希望:
//這只是在附加關系時進行過濾,因此會顯示所有用戶,但只會拉出匹配的地址
User::with(array('Addresses' => function($query){
$query->where('town', '=', 'Smallville');
}));
//這根本不起作用
User::with('Addresses')->where('user_addresses.town', '=', 'Smallville');
那么是否存在一種“雄辯”的方式,以過濾主要集合的方式將where子句應用於關系並保持我的雄辯對象? 或者我是否喜歡這么多其他人被Eloquent的優雅語法所破壞到我要求太多的地步?
注意:我知道你通常可以通過在另一個方向定義關系來解決這個問題(例如,首先訪問地址表),但這並不總是理想的,而不是我要求的。
在此先感謝您的幫助。
此時,您無法根據相關模型中的約束過濾主模型。 這意味着,您只能在一次滑動中獲得擁有user_address.town = 'Smallwille'
Users
。
我個人希望這會很快實現,因為我可以看到很多人要求它(包括我在這里)。
目前的解決方法很混亂,但它的工作原理:
$products = array();
$categories = Category::where('type', 'fruit')->get();
foreach($categories as $category)
{
$products = array_merge($products, $category->products);
}
return $products;
如問題所述,有一種方法可以先過濾地址,然后使用預先加載來加載相關的用戶對象。 如此:
$addressFilter = Addresses::with('Users')->where('town', $keyword)->first(); $users= $addressFilter->users;
當然在模型中與belongsTo綁定。
/// *如果有人想要也使用預過濾的用戶數據,你可以將一個閉包傳遞給'with'
$usersFilter = Addresses::with(array('Users' => function($query) use ($keyword){
$query->where('somefield', $keyword);
}))->where('town', $keyword)->first();
$myUsers = $usersFilter->users;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.