为了账号安全,请及时绑定邮箱和手机立即绑定

如何从 Laravel 中的疏远关系中提取字段

如何从 Laravel 中的疏远关系中提取字段

PHP
守候你守候我 2021-11-13 16:05:07
我有一个多对一的关系来获取每个产品的图像,每个产品都应该有很多图像供用户查看。所以当我这样做的时候,我试图获得带有图像的股票 public function getImages() {        $stocks = Stocks::with('images', 'tags')->get();        return $stocks;    }它返回这个[   {       "id": 7,       "name": "1",       "descriptions": "1",       "price": 1,       "discount": 1,       "category": "new",       "quantity": 1,       "brand": "1",       "created_at": "2019-08-04 09:07:25",       "updated_at": "2019-08-04 09:07:25",       "images": [           {               "id": 6,               "url": "1564909645iKiw2LkoEcQIIhB4MTZJTUfwTREleWH4wEuvmRPd.png",               "created_at": "2019-08-04 09:07:25",               "updated_at": "2019-08-04 09:07:25",               "pivot": {                   "stocks_id": 7,                   "images_id": 6               }           },           {               "id": 7,               "url": "1564909645OVxnM0qmoQayZrP7wq82pTmSj1AwQc9gioyC5L7h.png",               "created_at": "2019-08-04 09:07:25",               "updated_at": "2019-08-04 09:07:25",               "pivot": {                   "stocks_id": 7,                   "images_id": 7               }           }       ],       "tags": [           {               "id": 1,               "tag": "عطور",               "created_at": "2019-08-03 17:45:52",               "updated_at": "2019-08-03 17:45:52",               "pivot": {                   "stocks_id": 7,                   "tag_id": 1               }           }       ]   }]但我希望“图像”只有 url 作为字符串,例如:"images":[1.png,2.png,3.png .....]我该怎么办?我的关系public function images()    {        return $this->belongsToMany('App\Images', 'stock_images');    }
查看完整描述

3 回答

?
喵喵时光机

TA贡献1846条经验 获得超7个赞

但我希望“图像”只有 url 作为字符串,例如:

"images":[1.png,2.png,3.png .....]

我该怎么办?

最快的解决方案是将$visible属性添加到您的App\Images模型中,如下所示:

public $visible = ['url'];

这将从 json 中删除所有字段,包括pivot字段,但visible属性中定义的字段除外。此解决方案工作正常,但它仍然选择图像表中的所有列,如果您希望它只为关系选择最少的必填字段(以便提高性能),您可以执行以下操作:

$stocks = Stocks::with('images:url', 'tags')->get(); // this is a shortcut for selecting only url

请注意,上述解决方案适用于多对多 (N:N) 关系。但是,对于 hasMany (1:N),您还必须选择主键和所有相关的外键。

希望能帮助到你。

更新

它有效,但如何删除密钥 url: 并仅存储值 1,2,3


->pluck() 是执行此操作的集合函数,但是,您不能在不丢弃其余字段的情况下轻松地从远距离关系中提取字段,但是这个宏可以解决问题。


->pluckDistant()

在你AppServiceProvider的boot方法下,添加这个宏函数:


public function boot()

{

    /**

     * Shortcut to pluck a field in a relationship.

     *

     * @param string $relationship The relationship name

     * @param string|array $value

     * @param string|null $key

     */

    collect()->macro('pluckDistant', function($relationship, $value, $key = null) {

        return $this->map(function($item) use($relationship, $value, $key) {

            $relation = $item->getRelation($relationship);


            if (get_class($relation) == \Illuminate\Support\Collection::class ||

                get_class($relation) == \Illuminate\Database\Eloquent\Collection::class) {

                $item->setRelation($relationship, $relation->pluck($value, $key));

            }


            return $item;

        });

    });

}

然后,你这样做:


$stocks = Stocks::with('images:url', 'tags')->get()->pluckDistant('images', 'url');


查看完整回答
反对 回复 2021-11-13
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

您需要像这样进行查询:


$stocks = Stock::with(['tags','images' => function ($query) {

              $query->get()->pluck('url');

          }])->get();


查看完整回答
反对 回复 2021-11-13
?
holdtom

TA贡献1805条经验 获得超10个赞

您可以在急切加载与函数的关系时传递闭包with()。


在那个闭包中,您可以使用 select 函数来过滤列。


$stocks = Stock::with('tags')

              ->with(['images' => function ($query) {

                  $query->select(['id', 'url']);

              }])

              ->get();

更新


如果您只想要没有键的值,则不能使用此方法。您必须在从数据库中获取数据后执行此操作。像这样..


$stocks = Stock::with('images', 'tags')->get()->map(function ($stock) {

    $stock->images = $stock->images->map->url->values();


    $stock->unsetRelation('images');


    return $stock;

});


查看完整回答
反对 回复 2021-11-13
  • 3 回答
  • 0 关注
  • 131 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信