[英]Laravel relationship conflicts in union
我有以下 model:1-用戶 model
/**
* Define user and functional area relationship
*/
public function functionalAreas()
{
return $this->belongsToMany('App\FunctionalArea', 'user_functional_areas', 'user_id', 'functional_area_id')->withPivot('id', 'is_primary')->withTimestamps();
}
和業務 model:
/**
* Define business and user functional area relationship
*/
public function functionalAreas()
{
return $this->belongsToMany('App\FunctionalArea', 'business_functional_areas', 'business_id', 'functional_area_id')->withTimestamps();
}
現在我應該將所有企業和用戶顯示在一個列表中,為此我從聯合中使用,以下是我的查詢:
public function usersAndOrganizations()
{
$users = $this->users();
$organizations = $this->organizations();
$invitees = $users->union($organizations)->paginate(10);
return response()->json($invitees);
}
private function users()
{
$users = User::byState($approved = true, 'is_approved')
->search()->select([
'id',
DB::raw("CONCAT(first_name, ' ', last_name) AS name"),
'about',
'address',
'slug',
'average_reviews',
DB::raw("'freelancer' AS type")
]);
$users = $users->with([
"functionalAreas" => function ($q) {
$q->select([
'functional_areas.id',
DB::raw("functional_areas.name_en AS name"),
]);
}
]);
return $users;
}
private function organizations()
{
$businesses = Business::where('owner_id', '!=', auth()->user()->id)->verified()
->active()->search()
->select([
'id',
'name',
'about',
'address',
'slug',
'average_reviews',
DB::raw("'business' AS type")
]);
$businesses = $businesses
->with([
"functionalAreas" => function ($q) {
$q->select([
'functional_areas.id',
DB::raw("functional_areas.name_en AS name"),
]);
}
]);
return $businesses;
}
但是上面的查詢沒有返回業務功能區,它的output查詢是從用戶關系而不是業務中使用的, with
section會生成兩次如下查詢:
select
`functional_areas`.`id`,
functional_areas.name_en AS name,
`user_functional_areas`.`user_id` as `pivot_user_id`,
`user_functional_areas`.`functional_area_id` as `pivot_functional_area_id`,
`user_functional_areas`.`id` as `pivot_id`,
`user_functional_areas`.`is_primary` as `pivot_is_primary`,
`user_functional_areas`.`created_at` as `pivot_created_at`,
`user_functional_areas`.`updated_at` as `pivot_updated_at`
from `functional_areas`
inner join `user_functional_areas`
on `functional_areas`.`id` = `user_functional_areas`.`functional_area_id`
where `user_functional_areas`.`user_id` in (2, 6, 7)
但實際上 6 和 7 是業務 id 而不是用戶只有 2 是用戶 id,其中一個查詢應該使用business_functional_areas
而不是user_functional_areas
。 再發現一件事,結果中所有項目都在App\User
model 中,其類似的businesses
也為用戶 object。
簡而言之,目前您無法使用Eloquent Eager Loading
with Unions
來實現它。 Laravel 尚不支持此功能。 他們作為Non-Fix
問題關閉的其中一種情況是Union with Eloquent fail...。
Reason : While calling UNION
function only the first model( user
) is considered main model and model type of result set of other model( Business
) passed as argument will be converted to the main one( USER
) only and the main model relationship is called在所有記錄上(不是所需的記錄)。
由於上述問題,僅在結果集的每條記錄上調用user
model 的關系。 所以即使business_id = 1,user_id = 1 的functional_area 也會被獲取。
您可以從下面的文件和 function 中調試更多信息。
File:
<your_laravel_project>\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php
Function: get
替代解決方案您可以按原樣獲取兩個結果集,然后在使用 php 獲取數據后將它們合並。
public function usersAndOrganizations()
{
$users = $this->users()->get();
$organizations = $this->organizations()->get();
$invitees = $users->toBase()->merge($organizations->toBase())->toArray();
dd($invitees);
}
目前唯一的方法是使用map
。
public function usersAndOrganizations()
{
$users = $this->users();
$organizations = $this->organizations();
$invitees = $users->union($organizations)->paginate(10);
$invitees = $this->getRelatedData($invitees);
return response()->json($invitees);
}
private function getRelatedData($invitees)
{
$invitees->map(function($object) use($functionalAreaName) {
if($object->type == 'business') {
$relationName = 'businesses';
$relationKey = 'business_id';
$attachableType = Business::MORPHABLE_TYPE;
}
if($object->type == 'freelancer') {
$relationName = 'users';
$relationKey = 'user_id';
$attachableType = User::MORPHABLE_TYPE;
}
$functionalAreas = FunctionalArea::whereHas($relationName, function($q) use ($object, $relationKey){
$q->where($relationKey, $object->id);
})->get([$functionalAreaName.' As name', 'id']);
$object->functional_areas = $functionalAreas->toArray();
});
return $invitees;
}
並從你的函數中刪除with
並在你得到分頁結果后調用它。
您不能使用聯合連接不兼容的查詢。 請參閱工會。
您的users()
方法返回User
實體的 eloquent 構建器。 並且organizations()
返回Business
實體的構建器。
因此,一次查詢對 select 用戶和組織不正確。
正確的查詢是這樣的:
SELECT City FROM Customers
UNION
SELECT City FROM Suppliers
ORDER BY City;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.