Подтвердить что ты не робот

Динамически скрывать определенные столбцы при возврате объекта Eloquent как JSON?

Как динамически скрывать определенные столбцы при возврате объекта Eloquent как JSON? Например. чтобы скрыть столбец "пароль":

$users = User::all();
return Response::json($users);

Я знаю, что могу установить защищенные свойства в модели ($hidden или $visible), но как установить их динамически? Я мог бы скрыть или показать разные столбцы в разных контекстах.

4b9b3361

Ответ 1

$model->getHidden();
$model->setHidden(array $columns);

$model->setVisible(array $columns);

Ответ 2

Я нашел полное решение проблемы с использованием $model- > setHidden (массивы $columns);

Скажем, например, что вы хотели бы решить в контроллере точно, какие поля возвращать. Обновление только скрытой модели заставляет вас проходить каждую модель до того, как вы вернете массив моделей, например. Проблема становится еще хуже, когда эти модели имеют отношения, которые вы также хотели бы изменить. Вы должны перебрать каждую модель, установить скрытый атрибут, а затем для каждого также установить скрытые отношения. Какой беспорядок.

Мое решение включает в себя создание статического члена для каждой модели, которая, если присутствует, обновляет видимый/скрытый атрибут непосредственно перед вызовом "toArray":

<?php

trait DynamicHiddenVisible {

    public static $_hidden = null;
    public static $_visible = null;

    public static function setStaticHidden(array $value) {
        self::$_hidden = $value;
        return self::$_hidden;
    }

    public static function getStaticHidden() {
        return self::$_hidden;
    }

    public static function setStaticVisible(array $value) {
        self::$_visible = $value;
        return self::$_visible;
    }

    public static function getStaticVisible() {
        return self::$_visible;
    }

    public static function getDefaultHidden() {
        return with(new static)->getHidden();
    }

    public static function geDefaultVisible() {
        return with(new static)->getVisible();
    }

    public function toArray()    {
        if (self::getStaticVisible())
            $this->visible = self::getStaticVisible();
        else if (self::getStaticHidden())
            $this->hidden = self::getStaticHidden();
        return parent::toArray();
    }

}

В качестве дополнительного бонуса я раскрываю путь к скрытой/видимой по умолчанию модели, которую вы, возможно, установили в своем классе модели.

Не забывайте добавлять признак

class Client extends Eloquent {
     use DynamicHiddenVisible;
}

Наконец, в контроллере, прежде чем возвращать вашу модель, выберите видимые/скрытые атрибуты:

public function getIndex($clientId) {
    // in this specific call, I would like to hide the "special_type" field of my Client model
    $hiddenFields = Client::getDefaultHidden();
    array_push($hiddenFields, "special_type");
    Client::setStaticHidden($hiddenFields);

    return Client::find($clientId)->toJson();
}

Ответ 3

Я не верю, что ORM беспокоится о логике представления, и именно это JSON. Вам придётся передавать данные различным типам, а также скрывать вещи, а иногда создавать буферную зону для безопасного переименования.

Вы можете сделать все это с помощью Fractal, который я построил именно по этой причине.

<?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\ItemResource
     */
    public function includeAuthor(Book $book)
    {
        $author = $book->author;

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

Вложения (в том числе) могут быть немного больше, чем вам нужно прямо сейчас, но это может быть очень удобно.

Ответ 4

В дополнение к ответу @deczo - я чувствую, что переменная $hidden не предназначена для динамического использования. Это больше для защиты определенных данных от некорректного отображения (например, "пароль" ).

Если вам нужны определенные столбцы - вы, вероятно, должны просто использовать оператор select и просто получать нужные столбцы.

Ответ 5

От Документация Lavarel 5.3:

Временное изменение видимости атрибута

Если вы хотите, чтобы некоторые типичные скрытые атрибуты были видимыми в данном экземпляре модели, вы можете использовать метод makeVisible. Метод makeVisible возвращает экземпляр модели для удобной группировки методов:

return $user->makeVisible('attribute')->toArray();

Аналогично, если вы хотите сделать некоторые типично видимые атрибуты, скрытые в экземпляре данной модели, вы можете использовать метод makeHidden.

return $user->makeHidden('attribute')->toArray();

Ответ 6

В 5.4 вы можете скрыть и показать атрибуты динамически:

$model->makeVisible('attribute');

$model->makeHidden('attribute');

Laravel docs

Ответ 7

Для версии Laravel версии 5.3 или более поздней версии,

Если вы хотите сделать несколько атрибутов временными скрытыми или видимыми с помощью одного оператора, вы можете использовать методы model->makeVisible() и model->makeHidden() с передачей array of attributes.

Например, чтобы скрыть несколько атрибутов,

$user->makeHidden(["attribute1", "attribute2", "attribute3"]);

И чтобы сделать видимыми несколько атрибутов,

$user->makeVisible(["otherAttribute1", "otherAttribute2", "otherAttribute3"]);

Ответ 8

Создал пакет для этого, который использует модельные политики.

https://github.com/salomoni/authorized-attributes


Используйте Salomoni\AuthorizedAttributes trait

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Salomoni\AuthorizedAttributes;

class Post extends Model
{
    use AuthorizedAttributes;

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = ['author_comments'];
}

Создать и зарегистрировать политику модели. Добавьте методы для скрытых атрибутов в верблюжьем футляре с префиксом see.

namespace App\Policies;

use App\User;

class PostPolicy
{
    /**
     * Determine if a post author_comments-atrribute can be seen by the user.
     *
     * @param  \App\User  $user
     * @return bool
     */
    public function seeAuthorComments(User $user)
    {
        return $user->isAuthor();
    }
}