在将Eloquent对象作为JSON返回时,如何动态隐藏某些列?例如。隐藏“密码”列:
$users = User::all();
return Response::json($users);
我知道我可以在模型中设置受保护的属性( $ hidden 或 $ visible ),但如何动态设置?我可能想在不同的上下文中隐藏或显示不同的列。
答案 0 :(得分:34)
$model->getHidden();
$model->setHidden(array $columns);
$model->setVisible(array $columns);
答案 1 :(得分:14)
我使用$ model-> setHidden(array $ 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();
}
答案 2 :(得分:12)
如果您想在给定的模型实例上显示一些通常隐藏的属性,可以使用makeVisible
方法。 makeVisible
方法返回模型实例以方便方法链接:
return $user->makeVisible('attribute')->toArray();
同样,如果您想在给定的模型实例上隐藏一些典型的可见属性,您可以使用makeHidden
方法。
return $user->makeHidden('attribute')->toArray();
答案 3 :(得分: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);
}
}
嵌入(包括)内容可能比你现在需要的多一点,但它也可以非常方便。
答案 4 :(得分:8)
除了@ deczo的回答 - 我觉得$hidden
变量并非真正设计为动态使用。更多的是保护特定数据不被错误显示(例如“密码”)。
如果你想要特定的列 - 你应该只是使用一个select语句,只需获得你想要的特定列。
答案 5 :(得分:4)
答案 6 :(得分:1)
对于Laravel 5.3或更高版本,
如果您想使用单个语句临时隐藏或显示多个属性,则可以使用model->makeVisible()
和model->makeHidden()
方法传递array of attributes
。
例如,隐藏多个属性,
$user->makeHidden(["attribute1", "attribute2", "attribute3"]);
制作可见的多个属性,
$user->makeVisible(["otherAttribute1", "otherAttribute2", "otherAttribute3"]);
答案 7 :(得分:1)
为此制作了一个使用模型策略的软件包。
https://github.com/salomoni/authorized-attributes
使用Salomoni\AuthorizedAttributes
特征
<?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'];
}
Create and register a model policy。在驼峰式案例中添加前缀为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();
}
}
答案 8 :(得分:0)
在模型中:
protected $hidden = [
'your_field_1',
'your_field_2',
];