Дублированное значение в моем ответе JSON в Laravel

#php #laravel #laravel-permission

#php #laravel #laravel-разрешение

Вопрос:

Я создал метод show() в контроллере для возврата имени и временных меток всех разрешений, которые есть у этой роли. Spatie / Laravel-Permission отвечает за привязку пользователей к разрешениям и ролям в моем API.

     public function show($name)
    {
        $role = Role::findByName($name);
        return response()->json([
            $role,
            $role->permissions
        ]);
    }
  

Вывод:

 [
    {
        "name": "root",
        "created_at": "2019-04-08 19:41:49",
        "updated_at": "2019-04-08 19:41:49",
        "permissions": [
            {
                "name": "users.store"
            },
            {
                "name": "users.destroy"
            },
            {
                "name": "users.show.id"
            },
            {
                "name": "users.update.id"
            },
            {
                "name": "users.show.name"
            },
            {
                "name": "users.update.name"
            }
        ]
    },
    [
        // This is duplicate
        {
            "name": "users.store"
        },
        {
            "name": "users.destroy"
        },
        {
            "name": "users.show.id"
        },
        {
            "name": "users.update.id"
        },
        {
            "name": "users.show.name"
        },
        {
            "name": "users.update.name"
        }
    ]
]
  

Как вы можете видеть, дублирование разрешений бесполезно.

Но если я удалю $role из своего ответа

         return response()->json([
//            $role,
            $role->permissions
        ]);
  

Все в порядке

 [
    [
        {
            "name": "users.store"
        },
        {
            "name": "users.destroy"
        },
        {
            "name": "users.show.id"
        },
        {
            "name": "users.update.id"
        },
        {
            "name": "users.show.name"
        },
        {
            "name": "users.update.name"
        }
    ]
]
  

И когда я хочу вернуть только $ role без таких разрешений:

         return response()->json([
            $role,
//            $role->permissions
        ]);
  

Мой вывод:

 [
    {
        "name": "root",
        "created_at": "2019-04-08 19:41:49",
        "updated_at": "2019-04-08 19:41:49"
    }
]
  

Комментарии:

1. permissions никогда не определяется как свойство Role класса github.com/spatie/laravel-permission/blob/master/src/Models/… Оно используется только один раз [в этом классе], который я могу найти return $this->permissions->contains('id', $permission->id); в конце hasPermissionTo() Я не пользователь laravel, поэтому я не знаю, что extends Model имеет.

2. Возможно, хотя какой-то вспомогательный код, когда вы это делаете, $role->permissions заполняет значение (отложенная загрузка и т.д.), Вы можете попробовать вызвать это, прежде чем делать json что-то. $role->permissions; return response()->json([$role]); Чтобы проверить эту теорию, потому что, если она верна, тогда она должна быть заполнена в этом случае, где этого не было ранее (без вызова $role->permissions ). Тем не менее, могут быть способы быстро загрузить это и т.д. … Которые являются более надежными способами сделать то же самое.

3. Да, вы правы. Такого свойства, как permissions у Role model, нет, но есть что-то другое (к сожалению, у меня нет времени исследовать 🙂 ). Я нашел другой правильный способ достижения ожидаемого результата: github.com/spatie/laravel-permission/issues/876 Спасибо за помощь

4. $role->load('permissions'); быстрая загрузка. Вероятно, это правильный способ сделать это. Я просто не знаю Eloquent (но у меня есть модули сборки, поэтому я знаю, что они делают, как они это делают) и использовал такие вещи, как Doctrine (с некоторым разочарованием, работает нормально, скажем, вы получаете несколько миллионов строк… lol) и т.д….

Ответ №1:

Когда вы вызываете $role->permissions в своем ответе разрешения загружаются в $role объект, а затем сериализуются в json. Таким образом, в основном вы отправляете $role объект с загруженными разрешениями, и вы также отправляете сами разрешения.

Попробуйте:

 public function show($name)
{
    $role = Role::findByName($name)->load('permissions');

    return response()->json([
        $role
    ]);
}
  

Ответ №2:

вы можете использовать Eloquent: Ресурсы API здесь

 public function show($name)
{
    return new RoleResource(Role::findByName($name));
}
  

и RoleResource, подобный этому:

 <?php

namespace AppHttpResources;

use IlluminateHttpResourcesJsonJsonResource;

class RoleResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  IlluminateHttpRequest  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'name' => $this->name,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
            'permissions' => $this-> permissions,
        ];
    }
}