我正在开发基于Elequent ORM的REST API。 在请求单个对象时,我的查询返回类似的内容:
$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',
'...
有没有一种很好的方法可以用雄辩的方式实现这一目标?
答案 0 :(得分:2)
这取决于您使用的是什么版本的Laravel。对于Laravel的旧版本(5.4及以下版本),有一个名为Fractal的简单包,可以帮助您实现所需的目标。
Fractal为复杂提供了一个表示和转换层 数据输出,在RESTful API中找到的,并且工作得很好 与JSON。
以下是该代码的示例:
<div>
<app-personaldetails></app-personaldetails>
<app-contactdetails></app-contactdetails>
</div>
在较新版本(5.5+)中,您可以使用Eloquent Resources概念。
资源类表示单个模型 需要转换为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);
}
}
答案 1 :(得分:0)
试试这个:
$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;
});
答案 2 :(得分:0)
我认为您应该在attribute
中添加额外model
来处理此问题。所以你的model
应该是这样的:
e.g。
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
e.g。
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()
方法。
e.g。
//Inside controller
$records = Objects->where('somekey', 'somevalue')->get() ;
$records->setVisible(['shorttext', 'spacetext', 'description']);