Eloquent Api 资源:显示数据透视表中的一列

Posted

技术标签:

【中文标题】Eloquent Api 资源:显示数据透视表中的一列【英文标题】:Eloquent Api Resource: show one column from pivot table 【发布时间】:2021-07-02 04:34:13 【问题描述】:

我有一个车辆数据库,与我的变体和国家/地区表有多对多关系。我只想显示我的数据透视表 (countries_variants) 中的标题。但是当我在我的 api 资源文件中设置关系时,它会显示变量、国家变量和国家表中的所有列。有没有办法只从数据透视表中获取标题?

这是我的变体模型:

public function countries(): BelongsToMany

   return $this->belongsToMany(Country::class, 'countries_variants')->withPivot('title');
                

VariantResource.php

public function toArray($request)

  return [
      'title' => $this->countries->first->title,
  ];

VariantController.php

public function index()

   return new VariantCollection(Variant::paginate(50));

我得到的输出是:


 "data": [
    
      "title": 
        "id": 1,
        "title": "Nederland",
        "country_code": "NL",
        "language_code": "NL_nl",
        "pivot": 
          "variant_id": 1,
          "country_id": 1,
          "title": "3/5 deurs"
        
      
    
  ]

我只想显示"title": "3/5 deurs" 而不是其他数据。 我认为如果我在模型中设置 withPivot('title'),它只会显示该标题而不显示外键(variant_id 和 country_id)。显然是想错了..

我也试过添加这个:

'variant_title' => $this->whenPivotLoaded('countries_variants', function () 
  return $this->pivot->title;
),

但是数据然后返回空。

任何帮助将不胜感激:)

【问题讨论】:

【参考方案1】:

好吧,我终于想通了。我再次查看了官方的 laravel 文档,发现this。

所以我更改了 CountryVariant 模型类以扩展 Pivot 而不是 Model。

像这样:

use Illuminate\Database\Eloquent\Relations\Pivot;

class CountryVariant extends Pivot 
    public function variant(): BelongsTo
    
        return $this->belongsTo(Variant::class);
    

现在我在我的 VariantResource.php 中添加了这个:

public function toArray($request): array

   $items = [];

   foreach ($this->countries()->get() as $country) 
       $items[$country->language_code] = $country->pivot->only('title');
   

   return $items;

我还将数据透视表名称更改为单数,例如:country_variant(我是复数)。

显然问题在于,在我的模型中,它正在寻找我在数据透视表中没有的主键。我只有外键和一个附加列:'title'。它采用了我的一个外键并将其用作主键。因此,当我使用extends pivot 扩展时,它会忽略主键,我可以通过在资源文件中使用country->pivot->only('title') 来收集备用列“标题”。

我希望这对其他人有所帮助。

【讨论】:

【参考方案2】:

尝试改变

$this->countries->first->title

$this->countries->first->title->pivot->title

当您执行 withPivot('title') 时,您是在告诉 Eloquent 也获得 title 列,如果您不这样做,您将只会获得 keys(在您的情况下是 variant_idcountry_id)。

更多信息here。

【讨论】:

您好,感谢您的回复。但是,这也不起作用。当我按照你说的做时,我得到Trying to get property 'pivot' of non-object。我看到查询选择标题为countries_variants.title as pivot_title,所以我尝试将其设置为`$this->countries->first->pivot_title`,它返回空值。 你可以试试dd($this->contries->first),这样我们就可以看到那个对象有什么?但是您的解决方案就在这一行。 它确实显示了我的三个表(国家、变量和国家变量)中的数据集合。类似于我在帖子中显示的输出。它显示我想要的标题叫做 pivot_title 但我不明白为什么$this->countries->first->pivot_title 返回空值 很抱歉没有提供帮助。我认为它被称为pivot_title 因为访问器的工作方式,pivot->title 应该可以工作,但我不知道为什么不...我不需要像你那样从数据透视表中获取东西,这就是为什么我不是100% 确定。我会想点别的,然后再发表评论。 至少你会尽力帮忙,因此我已经很感激了;)

以上是关于Eloquent Api 资源:显示数据透视表中的一列的主要内容,如果未能解决你的问题,请参考以下文章

Eloquent 从数据透视表中获取数据

如何使用 Eloquent 在数据透视表中插入多行?

多对多关系 - 如何更新数据透视表中的属性

Laravel Eloquent - 附加与 SyncWithoutDetaching

SqlServer中的数据根据该表中某字段的值的结果决定是不是显示

如何通过 Eloquent 中具有多对多关系的外部表中的列聚合进行分组?