Laravel 5.6急切加载特定列不返回任何内容

12

我有两个类,ProductProductFormat。它们之间的关系已经被正确定义,我的Product拥有多个ProductFormat

public function formats()
{
    return $this->hasMany(ProductFormat::class);
}

当我尝试按照文档(https://laravel.com/docs/5.6/eloquent-relationships#eager-loading)中的方式,使用特定列来预载入关联关系时,它并没有按照预期工作。

例如,当我执行以下操作时:

Product::with('formats:id,upc')->get();
我收到的产品,格式空空如也。

我得到我的产品,到处都是空白格式。

{
    id: 1,
    formats: [ ]
}

然而,如果我这样做:

Product::with('formats')->get();
我得到了预期的格式,但有太多不必要的列。
{
    id: 1,
    formats: [
        {
            id: 1,
            upc: "101862422191",
            weight: 8.46,
            weight_unit: "kg"
        }
   ]
}

你在 product_format 表中有一个 product_id 字段吗? - Mkk
@Mkk 是的,我可以通过 $product->formats 正确获取关联。 - Chin Leung
我认为这种行为是针对单个对象关系的,就像文档中的 $users = App\Book::with('author:id,name')->get(); 是一个 belongsTo() 关系,而你正在使用一个 hasMany(),可能就是这个原因。 - Asur
4个回答

53

在关系中,您始终需要选择涉及到的外键/主键。在急切加载中也获取product_id,它就可以工作。

Product::with('formats:id,upc,product_id')->get();

我猜当获取HasMany关系时,你需要外键。但是当我获取一对一的关系时,我不需要它。 - Chin Leung
6
如果文档中提到了这点,那就更加有帮助了。 - Sammie
1
这是正确的答案!强制在每个子记录中获取父键毫无意义...特别是因为你已经在父级中拥有它。我会与Laravel团队讨论此问题。我完全同意文档应该修复hasMany()关系的问题。 - Juha Vehnia
我已经创建了拉取请求,以将此添加到文档中! - Juha Vehnia
已经在文档中了 https://laravel.com/docs/5.8/eloquent-relationships#eager-loading,请阅读标题 => 加载特定列 - Usman Jdn
@UsmanJdn 这在5.8文档中有提到,但在低版本文档中没有(5.5、5.6、5.7缺失)。 - bhanushalimahesh3

1
我遇到了这个问题,所以必须按照这种方式编写我的查询。除非从关系中获取到null值,否则您需要检索外键的ID。
Transaction::with([
    'client' => function($query){
        $query->select('id', 'first_name');
    }
])->get();

0

我遇到了同样的问题,但是我通过以下方式解决了它:

// Change this in model 
public function formats()
{
    return $this->hasMany(ProductFormat::class)->select(['id', 'upc']); 
}

// No need to join here. 
$data = Product::all();
foreach ($data as $key => $value) {
    echo "<pre>";
    print_r($value->formats);
}

通过这样做,您将获得所需的格式。


0

要在 Eager load 中获取特定的列,有两种方法:

方法1: 在您的 ProductFormat 模型中,设置 protected $visible = ['col_1,'col_2'];

方法2:

使用接受 Builder $query 作为参数的 closure

Product::with(['format' => function ($query) {     
$query->select('col_1', 'col_2'); 
})->get();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接