Laravel 一对多到 return ID 中的名称

Laravel One to Many to return names within ids

我有一个名为 items 的主 table,它有许多其他 table 的外键,例如 (categories, sections ..等)。

我在其他 table 与 items table 之间创建了 one-to-many 关系,因此每个类别都可以分配给多个项目,依此类推.

我想从其他 table 中获取填充有 namesitems table,而不仅仅是 ID。

所以它应该是这样的:

{id: 1, category_name: first, section_name: x .. }

我得到的是:

{id: 1, category_id: 1, section_id, 1}

我可以只从查询中获取名称吗?因为我想将它们作为 JSON 传递给 datatables.

这可能吗?

The idea 规范化数据库是为了避免重复数据并保持完整性。


选项 1:API 资源

现在针对您的情况,如果您尝试使用 Laravel 作为后端,您可以使用 5.5 版 Laravel 的新功能 API Resources。它可以帮助您格式化对象(例如模型或集合)的输出,以显示属性和关系。

因此,您可以在 ItemResource 资源中执行类似的操作:

App\Http\ResourcesResources\ItemResource.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class ItemResource extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @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 对象传递给 return:

use App\Http\Resources\ItemResource;

// 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:加载关系

另一种方法是 Eager Load or Lazy Eager Load 你的 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个选项。

  1. 使用连接表。参考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();

  1. 使用eloquent关系到模型的关系。因此,您可以调用,例如 $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 accessor 方法来做到这一点

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'];