Реструктурируйте Eloquent Collection для лучшего доступа к API - PullRequest
0 голосов
/ 01 июня 2018

Я работаю над REST API на основе Elequent ORM.Мой запрос возвращает что-то вроде этого при запросе одного объекта:

$data = $this->select('objects.*')->where('id', '=', $id)->get();

Коллекция:

[
    {
        "id": 3414,
        "type": 3,
        "title": "Title",
        "shorttext": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
        "spacetext": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
        "description": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."

    }
]

Поэтому я хотел бы изменить структуру, возвращаемую API, примерно так:

[
    {
        "id": 3414,
        "type": 3,
        "text" {
            "title": "Title",
            "shorttext": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
            "spacetext": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
            "description": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."
        }

    }
]

Таким образом, структура немного более прозрачна для пользователя доступа.Это, конечно, должно работать и при запросе не только одного объекта через GET, но и списка объектов.

Я пытался использовать коллекции красноречивых отображений через mapToGroups(), но ничего не получил.

Перед использованием Eloquent я использовал Medoo.Там мне просто нужно было ввести массив схем, как это, и все было сделано:

$this->schema = [
        'id', 
        'type',
        'text' => [
            'title',
            'shorttext',
            'spacetext',
            'description'
        ],
        'prices' => [
            'baseprice',
            '...

Есть ли хороший способ добиться этого с помощью eloquent?

Ответы [ 3 ]

0 голосов
/ 01 июня 2018

Это зависит от того, какую версию Laravel вы используете.Для более старых версий (5.4 и ниже) Laravel существует отличный простой пакет под названием Fractal , который поможет достичь того, что вы ищете.

Fractal предоставляет слой представления и преобразования для сложного вывода данных, подобный тому, который есть в RESTful API, и отлично работает с JSON.

Вот пример этогокод работы:

<?php namespace App\Transformer;

use Acme\Model\Book;
use League\Fractal\TransformerAbstract;

class BookTransformer extends TransformerAbstract
{
    /**
     * List of resources possible to include
     *
     * @var array
     */
    protected $availableIncludes = [
        'author'
    ];

    /**
     * Turn this item object into a generic array
     *
     * @return array
     */
    public function transform(Book $book)
    {
        return [
            'id'    => (int) $book->id,
            'title' => $book->title,
            'year'    => (int) $book->yr,
            'links'   => [
                [
                    'rel' => 'self',
                    'uri' => '/books/'.$book->id,
                ]
            ],
        ];
    }

    /**
     * Include Author
     *
     * @return \League\Fractal\Resource\Item
     */
    public function includeAuthor(Book $book)
    {
        $author = $book->author;

        return $this->item($author, new AuthorTransformer);
    }
}

В более новых версиях ( 5.5 + ) вы можете использовать концепцию Eloquent Resources .

AКласс ресурсов представляет собой единую модель, которую необходимо преобразовать в структуру JSON.Например, вот простой класс ресурсов:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class SampleModel extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'type' => $this->type,
            'text' => [
                'title' => $this->title,
                'short_text' => $this->short_text,
            ],
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}
0 голосов
/ 01 июня 2018

Я думаю, что вы должны справиться с этим, добавив attribute в ваш model.Таким образом, ваш model должен выглядеть следующим образом:

например

use Illuminate\Database\Eloquent\Model;

class Objects extends Model {

    protected $appends = ['text']; 

    public function getTextAttribute(){
        return array("shorttext" => $this->shorttext, "spacetext" => $this->spacetext, "description" => $this->description);
    }
}

Это даст вам желаемый результат.

Но вы также найдете все три столбца в стороне от JSON или Array.Поэтому необходимо установить его скрытым, если они не требуются, используя $hidden

например,

protected $hidden = ['shorttext', 'spacetext', 'description' ];  // add this line in your model if you want to hide these columns in response json or array.

Помните, что вы все равно можете получить доступ к этим свойствам, если только найдете или получите модель.Он будет установлен только на hidden when converted to JSON or Array или при возврате в ответ.Если вы хотите показать их, просто используйте метод setVisible().

например

//Inside controller
$records = Objects->where('somekey', 'somevalue')->get() ; 
$records->setVisible(['shorttext', 'spacetext', 'description']);
0 голосов
/ 01 июня 2018

Попробуйте это:

$remove = ["title", "shorttext", "spacetext", "description"];
$data->map(function($a) use($remove){
    foreach ($remove as $value) {
        $a["text"][$value] = $a[$value];
        unset($a[$value]);
    }
    return $a;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...