Laravel 5.6:雄辩的关系会改变集合数据

时间:2018-07-30 17:59:52

标签: php laravel eloquent

有没有一种方法可以调用雄辩的关系方法而无需更改该方法运行的原始雄辩的集合?当前,我必须使用一个临时集合来运行不可变的方法,并防止将整个相关记录添加到响应返回中:

$result = Item::find($id);
$array = array_values($result->toArray());
$temp = Item::find($id);
$title = $temp->article->title;

dd($temp); //This prints entire article record added to the temp collection data.

array_push($array, $title);

return response()->json($array);

3 个答案:

答案 0 :(得分:1)

我看到两种方法可以实现这一目标。

首先,您可以使用雄辩的资源。基本上,它允许您从模型中完全返回您想要的内容,因此,在这种情况下,您可以排除该文章。您可以找到文档here

第二种方法是相当新的,并且仍然没有文献记载(据我所知,它确实有效)。您可以使用unsetRelation方法。因此,就您而言,您只需要执行以下操作即可:

$article = $result->article; // The article is loaded
$result->unsetRelation('article'); // It is unloaded and will not appear in the response

您可以找到unsetRelation documentation here

答案 1 :(得分:1)

据我所知没有。在处理模型输出时,我通常会像这样手动构建它们:

$item = Item::find($id);

$result = $item->only('id', 'name', 'description', ...);
$result['title'] = $item->article->title;

return $result; 

如果您需要更多功能或可重复使用的解决方案,那么资源是您的最佳选择。

https://laravel.com/docs/5.6/eloquent-resources#concept-overview

答案 2 :(得分:1)

您不在这里处理集合,而在处理模型。 Item::find($id)将为您提供Item类的对象(如果找不到,则为null)。

据我所知,没有将关系存储到关系访问器中就无法加载它。但是您始终可以再次取消设置访问器,以删除已加载的关系(从内存中)。

以您的示例为例,该过程将产生:

$result = Item::find($id);
$title = $result->article->title;
unset($result->article);

return response()->json(array_merge($result->toArray(), [$title]));

以上方法有效,但不是很好的代码。相反,您可以做以下三件事之一:

  1. 使用attributesToArray()代替toArray()(合并属性和关系):

    $result = Item::find($id);
    return response()->json(array_merge($result->attributesToArray(), [$result->article->title]));
    
  2. Item类上添加自己的getter方法,该方法将返回所需的所有数据。然后在控制器中使用它:

    class Item
    {
        public function getMyData(): array
        {
            return array_merge($this->attributesToArray(), [$this->article->title]);
        }
    }
    

    控制器:

    $result = Item::find($id);
    return response()->json($result->getMyData());
    
  3. 创建您自己的响应资源:

    <?php
    
    namespace App\Http\Resources;
    
    use Illuminate\Http\Resources\Json\JsonResource;
    
    class ItemResource extends JsonResource
    {
        public function toArray($request)
        {
            return [
                'id' => $this->id,
                'name' => $this->name,
                'title' => $this->article->title,
                'author' => $this->article->author,
                'created_at' => $this->created_at,
                'updated_at' => $this->updated_at,
            ];
        }
    }
    

    然后可以这样使用:

    return new ItemResource(Item::find($id));
    

最干净的方法是选项3 。当然,您也可以使用$this->attributesToArray()而不是枚举字段,但是考虑到您可能会扩展模型并且不想公开新字段,枚举它们将在将来为您带来安全性。