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.iduser_documents.added_by 相互匹配,如果匹配则附加它。

由于您只选择了 first_namelast_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'))
    ->...