使用预先加载从雄辩关系中仅返回 json 中的一列


Returning only one column in json from eloquent relationship using eager loading

我在"产品"模型中有这个来映射产品和条形码之间的一对多关系:

public function barcodes(){
    return $this->hasMany('Barcode', 'productId', 'id')->select(['barcode', 'productId']);
}

接下来,此代码不仅为我提供了产品,还为对象数组中的每个条形码提供了信息。

public function search(){
    $results = Product::with('barcodes')->where('name', 'LIKE', 'theQueryString')->get();
    return Response::json($return);
}

这是一个示例输出:

{
    "results": [
        {
            "id": 1,
            "name": "Warehouse Box",
            "created_at": "2034-12-14 06:57:52",
            "updated_at": "2064-12-14 06:27:52",
            "barcodes": [
                {
                    "barcode": "0750028400400",
                    "productId": 1
                },
                {
                    "barcode": "123456789",
                    "productId": 1
                }
            ]
        }
    ]
}
我希望"条形码

"只是一个值数组,而不是返回对象数组的"条形码"。

换句话说,我想返回每个条形码对象中"条形码"列的值,而不是对象本身。

以下是我希望它看起来像的样子:

{
    "results": [
        {
            "id": 1,
            "name": "Warehouse Box",
            "created_at": "2034-12-14 06:57:52",
            "updated_at": "2064-12-14 06:27:52",
            "barcodes": [
                "0750028400400",
                "123456789"
            ]
        }
    ]
}

有没有一种快速而聪明的方法可以在Laravel中使用Eloquent做到这一点?

有一个lists(),它创建一个数组,其中包含集合中每个模型的一个属性。然而,问题是我们必须对模型中关系的每个结果都这样做。这意味着控制器中存在一个循环。(我们不想要这样(

相反,您可以在模型中覆盖toArray()(当您执行Response::json()时将调用(。在下面的代码中,我们用lists()结果覆盖barcodes

public function toArray(){
    $array = parent::toArray();
    $array['barcodes'] = $this->barcodes->lists('barcode');
    return $array;
}

可以将闭包传递给 with 方法,并使用 select 方法指定要选择的列:

public function search(){
    $results = Product::with(array('barcodes' => function($query) {
        return $query->select('barcode');
    }))->where('name', 'LIKE', 'theQueryString')->get();
    ...

然后,您可以使用 Laravel's Collection 类中提供的 collapse 方法:

$results->barcodes = $results->barcodes->collapse();