Laravel eloquent 未正确获取数据
Laravel eloquent not fetching the data properly
在我的 laravel vue 应用程序中我有两个 tables,user
table 和 user_document
table.
在我的 user_document
table 中,我有一个名为 added_by
的专栏。
此列存储 id
个用户。
我的应用程序中有两个角色,管理员和普通用户。
我的用户可以通过vue组件上传文件到系统。管理员也可以为其他用户上传文件。
并且用户可以在数据table中查看他们已经上传的文档详细信息。
在该数据table 中,我显示了一个名为 Added By
的列,它显示了上传文档的用户(用户自己或由管理员)。
我有以下控制器来获取和显示这些记录。
<?php
namespace App\Http\Controllers\Dashboard\Corporate\Employee;
use App\Company;
use App\Models\OtherDocument;
use App\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class CompanyEmployeeOtherDocumentsController extends Controller
{
/**
* @param string $locale
* @return \Illuminate\Http\JsonResponse
*/
public function index(string $locale, Company $company, User $user)
{
$otherDocuments = OtherDocument::where('user_id', $user->id)
->with('added_by_user')
->when(request('validity_status'), function ($query) {
$query->where(function ($query) {
$query->when( in_array('active', request('validity_status')), function ($query) {
$query->where(function (Builder $query) {
$query->whereDate('issued_at', '<=', Carbon::now())
->whereDate('expires_at', '>=', Carbon::now()->addMonth());
})->orWhere('is_valid_forever',1);
})->when( in_array('expires', request('validity_status')), function ($query) {
$query->orWhere(function (Builder $query) {
$query->whereDate('expires_at', '<=', Carbon::now()->addMonth())
->whereDate('expires_at', '>=', Carbon::now());
});
})->when( in_array('expired', request('validity_status')), function ($query) {
$query->orWhereDate('expires_at', '<', Carbon::now());
});
});
})
->when(request('search_text'), function ($query) {
$query->where('name', 'like', '%' . request('search_text') . '%');
})
->paginate(request('per_page',config('statguru.pagination.limit')));
for ($i=0; $i < count($otherDocuments); $i++) {
$addedByUser = $otherDocuments[$i]->added_by_user;
if ($addedByUser) {
$otherDocuments[$i]['added_user_name'] = $addedByUser->first_name . ' ' . $addedByUser->last_name;
}
}
return response()->json($otherDocuments);
}
}
在我的 vue 组件中,我有以下 header 数组,
HeaderArray() {
return [
{text: 'Certificate', value: 'certificate'},
{text: 'Added by', value: 'added_by_user_name'},
{text: 'Institute', value: 'institute'},
{text: 'Expiration', value: 'valid_date', classList: 'text-center'},
{text: 'Validity', value: 'validity_status', classList: 'text-center'},
{text: 'Verification', value: 'verification_status', classList: 'text-center'},
];
},
整个解决方案完美无缺。
但现在不再使用这个 for 循环
for ($i=0; $i < count($otherDocuments); $i++) {
$addedByUser = $otherDocuments[$i]->added_by_user;
if ($addedByUser) {
$otherDocuments[$i]['added_user_name'] = $addedByUser->first_name . ' ' . $addedByUser->last_name;
}
}
我正在尝试通过 eloquent
获得相同的结果
->with(['added_by_user' => function($q){
$q->select('first_name', 'last_name');
}])
当我用这个替换 for 循环时,它没有显示按用户的名字添加...。我需要在 eloquent 中更改哪里才能正确获取该数据?
我正在使用 laravel 9
更新
我已经根据下面的 Malkhazi Dartsmelidze 回答更新了我的代码。
但我无法在数据上显示名称table。
以下是我更新的控制器,
<?php
namespace App\Http\Controllers\Dashboard\Corporate\Employee;
use App\Company;
use App\Models\OtherDocument;
use App\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class CompanyEmployeeOtherDocumentsController extends Controller
{
/**
* @param string $locale
* @return \Illuminate\Http\JsonResponse
*/
public function index(string $locale, Company $company, User $user)
{
$otherDocuments = OtherDocument::where('user_id', $user->id)
->with(['added_by_user' => function($q){
$q->select('id', DB::raw('CONCAT(first_name, " ", last_name) as added_user_name'));
}])
->when(request('validity_status'), function ($query) {
$query->where(function ($query) {
$query->when( in_array('active', request('validity_status')), function ($query) {
$query->where(function (Builder $query) {
$query->whereDate('issued_at', '<=', Carbon::now())
->whereDate('expires_at', '>=', Carbon::now()->addMonth());
})->orWhere('is_valid_forever',1);
})->when( in_array('expires', request('validity_status')), function ($query) {
$query->orWhere(function (Builder $query) {
$query->whereDate('expires_at', '<=', Carbon::now()->addMonth())
->whereDate('expires_at', '>=', Carbon::now());
});
})->when( in_array('expired', request('validity_status')), function ($query) {
$query->orWhereDate('expires_at', '<', Carbon::now());
});
});
})
->when(request('search_text'), function ($query) {
$query->where('name', 'like', '%' . request('search_text') . '%');
})
->paginate(request('per_page',config('statguru.pagination.limit')));
return response()->json($otherDocuments);
}
}
下面是vue header数组,
HeaderArray() {
return [
{text: 'Certificate', value: 'certificate'},
{text: 'Added by', value: 'added_user_name'},
{text: 'Institute', value: 'institute'},
{text: 'Expiration', value: 'valid_date', classList: 'text-center'},
{text: 'Validity', value: 'validity_status', classList: 'text-center'},
{text: 'Verification', value: 'verification_status', classList: 'text-center'},
];
},
下面是我收到的数据
{
"id": 6,
"user_id": 941,
"added_by": 869,
"name": "driving licence",
"issued_at": "2022-04-06T22:00:00.000000Z",
"expires_at": "2022-04-29T22:00:00.000000Z",
"is_valid_forever": 0,
"document_url": null,
"document_number": null,
"file_name": "6-driving-licence.pdf",
"url": "users/941/other-documents/6-driving-licence.pdf",
"status": "EXPIRES",
"created_at": "2022-04-07T03:39:47.000000Z",
"updated_at": "2022-04-07T03:39:47.000000Z",
"deleted_at": null,
"expires_at_formatted": "30-04-2022",
"validity_status": "EXPIRES",
"remaining_days": 18,
"added_by_user": {
"id": 869,
"added_user_name": "Satya Nadella",
"country_code": null,
"formatted_date_of_birth": "2022-04-11",
"name": " ",
"company_role": "admin",
"profile_image": [
{
"url": "/img/statguru-user.png"
}
],
"inviter_user": "",
"country": null,
"media": [
]
}
},
你这里做错了:
->with(['added_by_user' => function($q){
$q->select('first_name', 'last_name');
}])
关系的工作方式是 laravel 遍历该查询的结果并将 users.id
与 user_documents.added_by
相互匹配,如果匹配则附加它。
由于您只选择了 first_name
和 last_name
列,因此其中的 id
总是 null
并且不匹配任何 user_documents
.
解决方案:
->with(['added_by_user' => function($q){
$q->select('id', 'first_name', 'last_name');
}])
更方便的获取全名的方法:
use Illuminate\Support\Facades\DB;
...
->with(['added_by_user' => function($q){
$q->select('id', DB::raw('CONCAT(first_name, " ", last_name) as added_user_name'));
}])
编辑:
由于前端要求 added_user_name
应该在对象的第一层,你应该通过结果映射并将 added_user_name
移动到第一层,或者加入 users
table 并从中得到结果:
但是,如果您使用分页,则不建议使用 map
解决方案。我只会使用 join
来写
使用join
:
从查询中删除 ->with
函数并将其替换为 join
。
OtherDocument::where('user_id', $user->id)
->join('users', 'users.id', '=', 'user_document.added_by') // do not know exact names of columns
->select(DB::raw('user_document.*'), DB::raw('CONCAT(first_name, " ", last_name) as added_user_name'))
->...
在我的 laravel vue 应用程序中我有两个 tables,user
table 和 user_document
table.
在我的 user_document
table 中,我有一个名为 added_by
的专栏。
此列存储 id
个用户。
我的应用程序中有两个角色,管理员和普通用户。
我的用户可以通过vue组件上传文件到系统。管理员也可以为其他用户上传文件。
并且用户可以在数据table中查看他们已经上传的文档详细信息。
在该数据table 中,我显示了一个名为 Added By
的列,它显示了上传文档的用户(用户自己或由管理员)。
我有以下控制器来获取和显示这些记录。
<?php
namespace App\Http\Controllers\Dashboard\Corporate\Employee;
use App\Company;
use App\Models\OtherDocument;
use App\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class CompanyEmployeeOtherDocumentsController extends Controller
{
/**
* @param string $locale
* @return \Illuminate\Http\JsonResponse
*/
public function index(string $locale, Company $company, User $user)
{
$otherDocuments = OtherDocument::where('user_id', $user->id)
->with('added_by_user')
->when(request('validity_status'), function ($query) {
$query->where(function ($query) {
$query->when( in_array('active', request('validity_status')), function ($query) {
$query->where(function (Builder $query) {
$query->whereDate('issued_at', '<=', Carbon::now())
->whereDate('expires_at', '>=', Carbon::now()->addMonth());
})->orWhere('is_valid_forever',1);
})->when( in_array('expires', request('validity_status')), function ($query) {
$query->orWhere(function (Builder $query) {
$query->whereDate('expires_at', '<=', Carbon::now()->addMonth())
->whereDate('expires_at', '>=', Carbon::now());
});
})->when( in_array('expired', request('validity_status')), function ($query) {
$query->orWhereDate('expires_at', '<', Carbon::now());
});
});
})
->when(request('search_text'), function ($query) {
$query->where('name', 'like', '%' . request('search_text') . '%');
})
->paginate(request('per_page',config('statguru.pagination.limit')));
for ($i=0; $i < count($otherDocuments); $i++) {
$addedByUser = $otherDocuments[$i]->added_by_user;
if ($addedByUser) {
$otherDocuments[$i]['added_user_name'] = $addedByUser->first_name . ' ' . $addedByUser->last_name;
}
}
return response()->json($otherDocuments);
}
}
在我的 vue 组件中,我有以下 header 数组,
HeaderArray() {
return [
{text: 'Certificate', value: 'certificate'},
{text: 'Added by', value: 'added_by_user_name'},
{text: 'Institute', value: 'institute'},
{text: 'Expiration', value: 'valid_date', classList: 'text-center'},
{text: 'Validity', value: 'validity_status', classList: 'text-center'},
{text: 'Verification', value: 'verification_status', classList: 'text-center'},
];
},
整个解决方案完美无缺。
但现在不再使用这个 for 循环
for ($i=0; $i < count($otherDocuments); $i++) {
$addedByUser = $otherDocuments[$i]->added_by_user;
if ($addedByUser) {
$otherDocuments[$i]['added_user_name'] = $addedByUser->first_name . ' ' . $addedByUser->last_name;
}
}
我正在尝试通过 eloquent
获得相同的结果->with(['added_by_user' => function($q){
$q->select('first_name', 'last_name');
}])
当我用这个替换 for 循环时,它没有显示按用户的名字添加...。我需要在 eloquent 中更改哪里才能正确获取该数据?
我正在使用 laravel 9
更新
我已经根据下面的 Malkhazi Dartsmelidze 回答更新了我的代码。
但我无法在数据上显示名称table。
以下是我更新的控制器,
<?php
namespace App\Http\Controllers\Dashboard\Corporate\Employee;
use App\Company;
use App\Models\OtherDocument;
use App\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class CompanyEmployeeOtherDocumentsController extends Controller
{
/**
* @param string $locale
* @return \Illuminate\Http\JsonResponse
*/
public function index(string $locale, Company $company, User $user)
{
$otherDocuments = OtherDocument::where('user_id', $user->id)
->with(['added_by_user' => function($q){
$q->select('id', DB::raw('CONCAT(first_name, " ", last_name) as added_user_name'));
}])
->when(request('validity_status'), function ($query) {
$query->where(function ($query) {
$query->when( in_array('active', request('validity_status')), function ($query) {
$query->where(function (Builder $query) {
$query->whereDate('issued_at', '<=', Carbon::now())
->whereDate('expires_at', '>=', Carbon::now()->addMonth());
})->orWhere('is_valid_forever',1);
})->when( in_array('expires', request('validity_status')), function ($query) {
$query->orWhere(function (Builder $query) {
$query->whereDate('expires_at', '<=', Carbon::now()->addMonth())
->whereDate('expires_at', '>=', Carbon::now());
});
})->when( in_array('expired', request('validity_status')), function ($query) {
$query->orWhereDate('expires_at', '<', Carbon::now());
});
});
})
->when(request('search_text'), function ($query) {
$query->where('name', 'like', '%' . request('search_text') . '%');
})
->paginate(request('per_page',config('statguru.pagination.limit')));
return response()->json($otherDocuments);
}
}
下面是vue header数组,
HeaderArray() {
return [
{text: 'Certificate', value: 'certificate'},
{text: 'Added by', value: 'added_user_name'},
{text: 'Institute', value: 'institute'},
{text: 'Expiration', value: 'valid_date', classList: 'text-center'},
{text: 'Validity', value: 'validity_status', classList: 'text-center'},
{text: 'Verification', value: 'verification_status', classList: 'text-center'},
];
},
下面是我收到的数据
{
"id": 6,
"user_id": 941,
"added_by": 869,
"name": "driving licence",
"issued_at": "2022-04-06T22:00:00.000000Z",
"expires_at": "2022-04-29T22:00:00.000000Z",
"is_valid_forever": 0,
"document_url": null,
"document_number": null,
"file_name": "6-driving-licence.pdf",
"url": "users/941/other-documents/6-driving-licence.pdf",
"status": "EXPIRES",
"created_at": "2022-04-07T03:39:47.000000Z",
"updated_at": "2022-04-07T03:39:47.000000Z",
"deleted_at": null,
"expires_at_formatted": "30-04-2022",
"validity_status": "EXPIRES",
"remaining_days": 18,
"added_by_user": {
"id": 869,
"added_user_name": "Satya Nadella",
"country_code": null,
"formatted_date_of_birth": "2022-04-11",
"name": " ",
"company_role": "admin",
"profile_image": [
{
"url": "/img/statguru-user.png"
}
],
"inviter_user": "",
"country": null,
"media": [
]
}
},
你这里做错了:
->with(['added_by_user' => function($q){
$q->select('first_name', 'last_name');
}])
关系的工作方式是 laravel 遍历该查询的结果并将 users.id
与 user_documents.added_by
相互匹配,如果匹配则附加它。
由于您只选择了 first_name
和 last_name
列,因此其中的 id
总是 null
并且不匹配任何 user_documents
.
解决方案:
->with(['added_by_user' => function($q){
$q->select('id', 'first_name', 'last_name');
}])
更方便的获取全名的方法:
use Illuminate\Support\Facades\DB;
...
->with(['added_by_user' => function($q){
$q->select('id', DB::raw('CONCAT(first_name, " ", last_name) as added_user_name'));
}])
编辑:
由于前端要求 added_user_name
应该在对象的第一层,你应该通过结果映射并将 added_user_name
移动到第一层,或者加入 users
table 并从中得到结果:
但是,如果您使用分页,则不建议使用 map
解决方案。我只会使用 join
使用join
:
从查询中删除 ->with
函数并将其替换为 join
。
OtherDocument::where('user_id', $user->id)
->join('users', 'users.id', '=', 'user_document.added_by') // do not know exact names of columns
->select(DB::raw('user_document.*'), DB::raw('CONCAT(first_name, " ", last_name) as added_user_name'))
->...