我有一个名为items
的主表,它有许多其他表的外键,如(categories
,sections
..等)。
我已经在其他表之间创建了items
表之间的one-to-many
关系,因此可以将每个类别分配给多个项目,依此类推。
我想让items
表充满来自其他表的names
,而不仅仅是 id。
所以它应该看起来像这样:
{id: 1, category_name: first, section_name: x .. }
我得到的是:
{id: 1, category_id: 1, section_id, 1}
我只能从查询中获取名称吗?因为我想将它们作为 JSON 传递给数据表。
这可能吗?
规范化数据库的想法是避免重复数据并保持完整性等。
选项 1:API 资源
现在对于您的情况,如果您尝试使用Laravel作为后端,则可以使用Laravel的5.5版本称为API资源的新功能。它可以帮助您格式化对象(如模型或集合)的输出,以显示属性和关系。
因此,您可以在ItemResource
资源中执行以下操作:
App\Http\ResourcesResources\ItemResource.php
<?php
namespace AppHttpResources;
use IlluminateHttpResourcesJsonResource;
class ItemResource extends Resource
{
/**
* Transform the resource into an array.
*
* @param IlluminateHttpRequest
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->user_id,
// To access relationship attributes:
'category_name' => $this->category->name,
'section_name' => $this->section->name,
];
}
}
然后在控制器中,您只需创建一个新的ItemResource
实例并传递要返回的Item
对象:
use AppHttpResourcesItemResource;
// some code
/**
* Show a single formatted resource.
*
* @param Item $item
* @return ItemResource
*/
public function show($item)
{
return new ItemResource($item);
}
// the rest of your code
输出将是预期的。
选项 2:加载关系
执行此操作的另一种方法是预先加载或延迟预先加载Item
对象中的关系,如下所示:
// some code
/**
* Return a single item object.
*
* @param integer $id
* @return ItemResource
*/
public function show($id)
{
$item = Item::find($id);
$item->load(['category','section','etc']); // all of your relationships
return $item;
}
// the rest of your code
这将输出$item
但包含嵌套数据,例如:
{
"id":51,
"name": "Some item name",
"category": {
"id": 21,
"name": "category name"
}
"section": {
"id": 21,
"name": "section name"
}
.
.
.
}
然后在您的视图中,您只需访问以下属性:$item->category->name
我想到2个选项。
- 使用联接表。参考 https://laravel.com/docs/5.5/queries#joins
例如:
$data = DB::table('data')
->join('categories', 'categories.id', '=', 'data.category_id')
->join('sections', 'sections.id', '=', 'data.section_id')
->select('data.id', 'categories.name as category_name', 'sections.name as section_name')
->get();
- 使用雄辩关系来表示模型的关系。因此,您可以调用,例如
$data->category->name
调用类别的名称或$data->section->name
调用部分的名称。参考资料:https://laravel.com/docs/5.5/eloquent-relationships#one-to-many。
如果要使用选项2并想将其放入行中,则可以使用Laravel集合(地图功能)(https://laravel.com/docs/5.5/collections)
你可以通过使用 laravel 访问器方法来做到这一点,比如
class Item extends Model
{
/**
* Get the user's first name.
*
* @param string $value
* @return string
*/
public function getCategoryNameAttribute()
{ //Your model relation here
return $this->categories()->first()->category_name;
}
}
你可以对section_name做同样的事情
注意:如果要在 JSON 中获取protected $appends = ['category_name'];
,请在项目模型中使用它