【问题标题】:Laravel One to Many to return names within idsLaravel 一对多返回 ids 中的名称
【发布时间】:2018-04-19 07:49:56
【问题描述】:

我有一个名为items 的主表,其中有许多其他表的外键,例如(categoriessections .. 等)。

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

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

所以它应该是这样的:

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

我得到的是:

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

我可以仅从查询中获取名称吗?因为我想将它们作为 JSON 传递给数据表。

这可能吗?

【问题讨论】:

  • 如果您将 items 表与其他表连接起来,您可以这样做。或者只需为所有表定义模型,您就可以使用 Eloquent 的强大功能轻松获取所有数据。
  • @jedrzej.kurylo 我确实定义了所有模型,但无法从两个表中获取包含完整记录的一行数据(就像 JOIN 一样)。
  • 我不知道你以后会用这些数据做什么,一般来说模型应该是你最好的选择,但如果你真的想把所有东西都放在一行中,那么连接是你唯一的选择选项 - 请参阅此处的文档 laravel.com/docs/5.5/queries#joins
  • @jedrzej.kurylo 只想显示多个表中的特定行。
  • @jedrzej.kurylo 假设我想显示名称而不是 ID。

标签: laravel model eloquent laravel-5.5


【解决方案1】:

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


选项 1:API 资源

现在,对于您的情况,如果您尝试使用 Laravel 作为后端,您可以使用 Laravel 5.5 版本的新功能 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 对象:

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 LoadLazy 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-&gt;category-&gt;name

【讨论】:

  • 这太棒了,足够接近我正在寻找的东西,只是试图克服嵌套的。
  • @CairoCoder 这就是我从选项 1 开始的原因。使用 API 资源完全按照您需要的方式返回数据。检查this video 以获得帮助或直接访问文档(链接在响应中)。
【解决方案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. 使用雄辩的关系来建立关系模型。因此,您可以调用,例如$data-&gt;category-&gt;name 调用类别名称或$data-&gt;section-&gt;name 调用部分名称。参考:https://laravel.com/docs/5.5/eloquent-relationships#one-to-many

如果您想使用选项 2 并将其放入行中,您可以使用 Laravel Collection (map function) (https://laravel.com/docs/5.5/collections)

【讨论】:

  • 我可以将它们全部放在行中吗,因为我想将它们作为 JSON 传递给数据表。
  • 使用选项 1 会更简单,我更新了示例 @CairoCoder
【解决方案3】:

你可以通过使用 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'];

【讨论】:

  • 会试一试的。
猜你喜欢
  • 2020-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-28
  • 2012-11-26
  • 2019-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多