将Eloquent对象作为JSON返回时动态隐藏某些列?

mtm*_*ald 28 laravel eloquent laravel-4

在将Eloquent对象作为JSON返回时,如何动态隐藏某些列?例如,隐藏"密码"列:

$users = User::all();
return Response::json($users);
Run Code Online (Sandbox Code Playgroud)

我知道我可以在模型中设置受保护的属性($ hidden$ visible),但是如何动态设置它们呢?我可能想在不同的上下文中隐藏或显示不同的列.

Jar*_*zyk 35

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

$model->setVisible(array $columns);
Run Code Online (Sandbox Code Playgroud)

  • @hugomosh它在实例范围内工作,因此除非你再次设置,否则将为被调用的实例隐藏`something`.但是没有其他型号会受到影响. (3认同)

NiR*_*iRR 14

我使用$ model-> setHidden(array $ columns)找到了解决问题的完整解决方案;

让我们说,例如,您想要在控制器中确定要返回哪些字段.在返回模型数组之前,仅更新模型的隐藏会强制您遍历每个模型.当这些模型具有您想要改变的关系时,问题变得更加严重.您必须遍历每个模型,设置隐藏属性,然后为每个模型设置隐藏的关系.真是一团糟.

我的解决方案涉及为每个模型创建一个静态成员,当存在时,在调用"toArray"之前更新visible/hidden属性:

<?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();
    }

}
Run Code Online (Sandbox Code Playgroud)

作为额外的奖励,我公开了一种方法,可以在模型的类中设置模型的默认隐藏/可见.

不要忘记添加特征

class Client extends Eloquent {
     use DynamicHiddenVisible;
}
Run Code Online (Sandbox Code Playgroud)

最后,在控制器中,在返回模型之前,决定可见/隐藏属性:

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();
}
Run Code Online (Sandbox Code Playgroud)


All*_*pps 12

来自Lavarel 5.3文档:

暂时修改属性可见性

如果您想在给定的模型实例上显示一些通常隐藏的属性,则可以使用该makeVisible方法.该makeVisible方法返回模型实例以方便方法链接:

return $user->makeVisible('attribute')->toArray();
Run Code Online (Sandbox Code Playgroud)

同样,如果您想在给定的模型实例上隐藏一些典型的可见属性,您可以使用该makeHidden方法.

return $user->makeHidden('attribute')->toArray();
Run Code Online (Sandbox Code Playgroud)


Phi*_*eon 10

我不相信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);
    }
}
Run Code Online (Sandbox Code Playgroud)

嵌入(包括)东西可能比你现在需要的多一点,但它也可以非常方便.


Lau*_*nce 8

除了@ deczo的答案之外 - 我觉得这个$hidden变量并没有真正设计成动态使用.更多的是保护特定数据不被错误显示(例如"密码").

如果你想要特定的列 - 你应该只是使用一个select语句,只需获得你想要的特定列.


Luc*_* C. 5

在5.4中,您可以动态隐藏和显示属性:

$model->makeVisible('attribute');

$model->makeHidden('attribute');
Run Code Online (Sandbox Code Playgroud)

Laravel文档