Laravel加载特定资源的所有关系

时间:2019-07-08 10:57:01

标签: php laravel

我的模型如下,定义了fields关系。

//Stream.php
    /**
     * A stream can have many fields
     *
     * @return Illuminate\Database\Eloquent\Model
     */
    public function fields()
    {
        return $this->hasMany(Field::class);
    }

在我的数据库中,我有两个流:

//table: streams
id | name
1  | doc_stream
2  | email_stream

还有4个字段:

//table: fields
id | stream_id | name
1  | 1         | Field #1
2  | 1         | Field #2
3  | 1         | Field #3
4  | 2         | Field #4

因此,通过这种设置,我认为我可以简单地做到:

//streams/1/fields/1
public function show(Stream $stream, Field $field)
{
   dd($stream->with('fields')->get());
}

然后将返回所有字段,仅返回$stream.id = 1

但是,该关系会加载所有流:

enter image description here

我不能只为显示的特定资源加载关系吗?

2 个答案:

答案 0 :(得分:4)

您似乎正在使用route model binding来解析$field。然后使用$stream->with('fields')->get();来加载关系。

一切都按预期进行,我认为这里对路由模型绑定和关系的工作方式存在误解。

$stream->with('fields')->get();

这将加载所有流,因为它会启动新查询,并且与执行Stream::with('fields')->get()相同。

如果您想为自己的视频流指定特定字段,可以执行以下操作:

$field = $stream->fields()->findOrFail($fieldId);

在您的控制器方法中,看起来像这样

// streams/1/fields/1
public function show(Stream $stream, $fieldId)
{
   // findOrFail will throw a 404 if the field could not be found for the specific stream
   $field = $stream->fields()->findOrFail($fieldId);

   dd($field);
}
标识为$stream

1(对于您的示例URL)将通过路由模型绑定来解决。

否则,如果您设置了正确的路由模型绑定,这可能已经起作用:

// streams/1/fields/1
public function show(Stream $stream, Field $field)
{
   dd($field);
}

但是,这也将为另一个流(不属于该流)加载一个字段,因为它不知道如何对ID为1的流进行查询。

答案 1 :(得分:0)

我认为流表应具有属性field_id,并且应按如下所示编辑函数:

public function fields()
 {
    return $this->hasMany(Field::class, 'field_id', 'id');
 }