laravel 将 Eloquent 对象作为 JSON 返回时动态隐藏某些列?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24758603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamically hide certain columns when returning an Eloquent object as JSON?
提问by mtmacdonald
How do dynamically hide certain columns when returning an Eloquent object as JSON? E.g. to hide the 'password' column:
将 Eloquent 对象作为 JSON 返回时如何动态隐藏某些列?例如隐藏“密码”列:
$users = User::all();
return Response::json($users);
I'm aware I can set protected properties in the model ($hiddenor $visible), but how do I set these dynamically? I might want to hide or show different columns in different contexts.
我知道我可以在模型中设置受保护的属性($hidden或$visible),但是如何动态设置这些属性?我可能想在不同的上下文中隐藏或显示不同的列。
回答by Jarek Tkaczyk
$model->getHidden();
$model->setHidden(array $columns);
$model->setVisible(array $columns);
回答by NiRR
I've found a complete solution around the problem with using $model->setHidden(array $columns);
我找到了一个完整的解决方案,解决了使用 $model->setHidden(array $columns); 的问题。
Lets say, for example, that you would like to decide in the controller exactly which fields to return. Updating only the model's hidden forces you to go over each model before you return an array of models for example. The problem becomes even worse when those models have relationships that you would also like to change. You have to loop over each model, set the hidden attribute, and then for each also set the relationships hidden. What a mess.
例如,假设您希望在控制器中准确决定要返回哪些字段。例如,仅更新模型的隐藏会迫使您在返回模型数组之前检查每个模型。当这些模型具有您也想更改的关系时,问题会变得更糟。您必须遍历每个模型,设置隐藏属性,然后为每个模型设置隐藏关系。真是一团糟。
My solution involves creating a static member for each model that when present, updates the visible/hidden attribute just before the call to "toArray":
我的解决方案涉及为每个模型创建一个静态成员,当存在时,在调用“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();
}
}
As an added bonus, I expose a way to the model's default hidden/visible that you may have set in your model's class.
作为额外的奖励,我公开了一种模型默认隐藏/可见的方法,您可能已经在模型的类中设置了该方法。
Don't to forget to add the trait
不要忘记添加特征
class Client extends Eloquent {
use DynamicHiddenVisible;
}
Finally, in the controller, before returning your model, decide on visible/hidden attributes:
最后,在控制器中,在返回模型之前,决定可见/隐藏属性:
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();
}
回答by Allan Stepps
From Lavarel 5.3 Documentation:
Temporarily Modifying Attribute Visibility
临时修改属性可见性
If you would like to make some typically hidden attributes visible on a given model instance, you may use the makeVisible
method. The makeVisible
method returns the model instance for convenient method chaining:
如果您想让一些典型的隐藏属性在给定的模型实例上可见,您可以使用该makeVisible
方法。该makeVisible
方法返回模型实例以方便方法链接:
return $user->makeVisible('attribute')->toArray();
Likewise, if you would like to make some typically visible attributes hidden on a given model instance, you may use the makeHidden
method.
同样,如果您想在给定的模型实例上隐藏一些通常可见的属性,您可以使用该makeHidden
方法。
return $user->makeHidden('attribute')->toArray();
回答by Phil Sturgeon
I don't believe it is the job of the ORM to worry about presentation logic, and that is what JSON is. You'll aways need to cast data to various types as well as hide things and sometimes create a buffer zone to rename things safely.
我不相信 ORM 的工作是担心表示逻辑,这就是 JSON。您将需要将数据转换为各种类型以及隐藏内容,有时还需要创建缓冲区来安全地重命名内容。
You can do all of that with Fractalwhich I built for exactly this reason.
您可以使用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);
}
}
Embedding (including) stuff might be a bit more than you need right now, but it can be very handy too.
嵌入(包括)内容可能比您现在需要的要多一些,但它也非常方便。
回答by Laurence
In addition to @deczo's answer - I feel the $hidden
variable is not really designed to be used dynamically. It is more to protect specific data from ever been incorrectly displayed (such as 'password').
除了@deczo 的回答 - 我觉得该$hidden
变量并不是真正设计为动态使用的。更重要的是保护特定数据不被错误显示(例如“密码”)。
If you want specific columns - you should probably just be using a select statement and just get the specific columns you want.
如果您想要特定的列 - 您可能应该只使用 select 语句并获取您想要的特定列。
回答by Luca C.
In 5.4 you can hide and show attributes dinamically:
在 5.4 中,您可以动态地隐藏和显示属性:
$model->makeVisible('attribute');
$model->makeHidden('attribute');
回答by Dev
For Laravel 5.3 or greater version,
对于 Laravel 5.3 或更高版本,
If you want to make multiple attributes temporary hidden or visible using single statement, you may use model->makeVisible()
and model->makeHidden()
methods with passing array of attributes
.
如果您想使用单个语句使多个属性临时隐藏或可见,您可以使用model->makeVisible()
和model->makeHidden()
方法通过array of attributes
.
For example, to hide multiple attributes,
例如,要隐藏多个属性,
$user->makeHidden(["attribute1", "attribute2", "attribute3"]);
And to make visible multiple attributes,
并且使人们看到多个属性,
$user->makeVisible(["otherAttribute1", "otherAttribute2", "otherAttribute3"]);
回答by Jari Pekkala
Made a package for this that uses Model Policies.
为此制作了一个使用模型策略的包。
https://github.com/salomoni/authorized-attributes
https://github.com/salomoni/authorized-attributes
Use the Salomoni\AuthorizedAttributes
trait
使用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. Add methods for the hidden attributes in camel-case prefixed with see
.
创建并注册模型策略。以驼峰命名为前缀的隐藏属性添加方法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();
}
}