从 Laravel 中的 Mysql Pivot 表中获取列并返回 JSON 对象

Posted

技术标签:

【中文标题】从 Laravel 中的 Mysql Pivot 表中获取列并返回 JSON 对象【英文标题】:Getting column from a Mysql Pivot table in Laravel and returning a JSON object 【发布时间】:2020-01-06 03:05:18 【问题描述】:

我正在开发一个使用 Laravel 构建的应用程序,在后端,我在两个表之间有一些雄辩的多对多关系,主要是角色和权限。还有一个名为 role_permission 的数据透视表。我在模型中创建了关系,并且在控制器中捕获了以下值来创建权限:name、description、slug、role_id

在逻辑上,将名称、描述和 slug 存储在权限表中,而角色 ID 存储在数据透视表 (role_permission) 中。这工作正常。在响应中,我获取存储在权限表中的所有权限并显示为 JSON 对象。

问题是我想获取数据透视表中的 role_id 并附加到每个显示为响应的 JSON 对象。

榜样

<?php

namespace Modules\API\Entities;
use Modules\API\Entities\Permission;

use Illuminate\Database\Eloquent\Model;

class Role extends Model

    protected $fillable = ['name' , 'slug' , 'description'];

    /**
     * A role has more than one permission
    */
    public function permissions()
        return $this->belongsToMany(Permission::class , 'role_permission');
    

权限模型

<?php

namespace Modules\API\Entities;
use Modules\API\Entities\Role;
use Illuminate\Database\Eloquent\Model;

class Permission extends Model

    protected $fillable = ['name' , 'slug' , 'description'];

     /**
     * A permission has more than one role
    */
    public function roles()
        return $this->belongsToMany(Role::class , 'role_permission');
    

控制器文件(PermissionController.php)

<?php

namespace Modules\API\Http\Controllers;

use Carbon\Carbon;
use Modules\API\Common\helpers\GeneralHelper;
use Illuminate\Http\Request;
use Illuminate\Database\QueryException;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Validator;
use Modules\API\Entities\Permission;

class PermissionController extends Controller

    protected $requestTime;
    protected $reference_number;

    public function __construct()
    
        $this->requestTime = Carbon::now()->toDateTimeString();
    

    public function createPermission(Request $request) 

        $validator = Validator::make($request->all(), [ 
            'name' => 'required',
            "slug" => 'required',
        ]); 

        if ($validator->fails())           
            $response = GeneralHelper::failureException("Validation Failed", $validator->errors()->all(), Carbon::now()->toDateTimeString());
        
        else

            $name = $request->name;
            $description = isset($request->description) ? $request->description : null;
            $slug = isset($request->slug) ? $request->slug : null;
            $role = isset($request->role_id) ? $request->role_id : null;

            try
                $permission = new Permission;
                $permission->name = $name;
                $permission->slug = $slug;
                $permission->description = $description;
                $permission->save();

                //Attach role to pivot table if permission is saved
                if($permission->save() && !is_null($role))
                    $permission->roles()->attach($role);
                

                //Select specific columns from permissions table and return a JSON object
                $permissions = Permission::select('id' , 'name', 'slug', 'description')->get()->toArray();

                $response = response()->json(GeneralHelper::success("Permision Successfully added", "data", $permissions , Carbon::now()->toDateTimeString()));
             catch(QueryException $e)
                $response = response()->json(GeneralHelper::failureException("Database Exception", $e->getMessage() . " at LINE " . $e->getLine(), Carbon::now()->toDateTimeString()), Response::HTTP_INTERNAL_SERVER_ERROR);
            
        
        return $response;
   

经过上述逻辑后在 POSTMAN 中的示例响应


    "request_time": "2019-09-03 07:54:54",
    "response_time": "2019-09-03 07:54:54",
    "status": "success",
    "message": "Permision Successfully added",
    "data": [
        
            "id": 1,
            "name": "Create Post",
            "slug": "craete-post",
            "description": "mnmnmn"
        ,
        
            "id": 3,
            "name": "delete User",
            "slug": "del-user",
            "description": "mnmnmn"
        ,
        
            "id": 5,
            "name": "Create User",
            "slug": "create-user",
            "description": "mnmnmn"
        
    ]

更新回复


    "request_time": "2019-09-03 09:16:46",
    "response_time": "2019-09-03 09:16:46",
    "status": "success",
    "message": "Permision Successfully added",
    "data": [
        
            "id": 1,
            "name": "Kingston",
            "slug": "kingston-red-iuy",
            "description": "mnaskjas",
            "roles": [
                
                    "id": 3,
                    "name": "Editor",
                    "slug": "editor",
                    "description": "Editor",
                    "created_at": "2019-09-02 06:37:08",
                    "updated_at": "2019-09-02 06:37:08",
                    "pivot": 
                        "permission_id": 9,
                        "role_id": 3
                    
                
            ]
        
    ]
`  

在逻辑中使用此命令后:

 $permissions = Permission::select('id' , 'name', 'slug', 'description')->with('roles')->get()->toArray();

【问题讨论】:

【参考方案1】:

尝试改变:

$permissions = Permission::select('id' , 'name', 'slug', 'description')->get()->toArray();

进入:

$permissions = Permission::select('id' , 'name', 'slug', 'description')->with('roles')->get()->toArray();

$mappedPermissions = array_map(function ($permission)  
    $permission['role_id'] = data_get($permission, '0.pivot.role_id');

    unset($permission['roles']); 

    return $permission; 
, $permissions);

// Then use the $mappedPermissions from here on.

【讨论】:

非常感谢它的工作原理,如何从数据透视表中获取特定列的值??,检查更新的答案 您可以使用:-&gt;with('roles:id') 或查看这个 SO 主题:***.com/questions/19852927/…(请不要忘记给 anwser 投票) 我已经更新了我的问题,请检查一下,我正在尝试访问角色数组中枢轴对象中的 role_id.. 因为权限可以有多个规则,所以你不能得到一个role_id。你可以做的是,映射数组:$mappedPermissions = array_map(function ($permission) $permission['role_id'] = data_get($permission, '0.pivot.role_id'); unset($permission['roles']); return $permission; , $permissions); 可能data_get($permission, '0.pivot.role_id') 部分不正确。您可以通过dd($permission[0]) 进行调试,看看它输出了什么,然后看看我哪里出错了:D

以上是关于从 Laravel 中的 Mysql Pivot 表中获取列并返回 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 多对多合并 Pivot?

如何在 laravel 8 的 pivot_table 中调用其 id 作为 foreign_id 传递的主表中的列?

Laravel 5 更新所有 Pivot 条目

MySQL 中的 Pivot - 根据日期时间列显示第一个和最后一个值

使用 Pivot 在 MySQL 8.0.17 版中从不同表和不同行号(联合)进行行到列转换

Laravel Pivot - 通过相关模型获得相同的模型