【问题标题】:Laravel reducing queries and understanding appendsLaravel 减少查询和理解附加
【发布时间】:2018-07-12 15:07:02
【问题描述】:

我有 3 个模型,CategoryDescriptionExpense

每个类别hasMany 描述和一个描述belongsTo 一个类别,每个描述hasMany 费用,每个费用belongsTo 一个描述。

现在我有一个简单的categories.index 页面来显示所有类别。但是对于显示的每个类别,我想显示该类别所有费用的总和。我有这样的hasManyThrough 关系:

类别模型:

public function expenses()
{
    return $this->hasManyThrough(Expense::class, Description::class);
}

现在在我看来,我可以做到以下几点:

@foreach($categories as $category)
    {{ $category->expenses()->sum('amount')
@endforeach

这是我的第一个问题。在我的控制器中,我渴望加载描述和费用:

$categories = auth()->user()->categories()
        ->with('descriptions')
        ->with('expenses')
        ->get());

这是否意味着我不会针对当前视图的设置方式创建额外的查询?我认为确实如此,这很糟糕,但我不确定,只是试图理解它。我的第二个问题是:

我尝试在我的类别模型中添加它,但它没有向我的类别对象添加任何内容:

protected $appends = ['expenses'];

public function getExpensesAttribute()
{
    return $this->expenses()->sum('amount');
}

它只是显示了这个:

    #attributes: array:7 [▼
      "id" => 1
      "user_id" => 1
      "name" => "My Category"
      "slug" => "my-category"
      "created_at" => "2018-07-10 18:45:46"
      "updated_at" => "2018-07-10 18:45:46"
    ]

我认为我用错了/不理解它。对此的任何解释都会有所帮助。

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    附加不会添加到内部属性,但如果您使用toArray() 或发送对象的 JSON 响应,您应该会看到它们。您不希望将它们添加到属性中,因为属性用于更新数据库中的模型并且您不会有费用列。


    警告:您不应命名您的 mutator 费用,因为这会与您的费用关系相冲突。


    在这种情况下,急切加载关系不会做任何事情,因为您是在 mutator 中查询关系而不是访问现有的关系集合。

    如果你打算总是急于加载费用,那么你应该改变

    $this->expenses()->sum('amount');

    $this->expenses->sum('amount');

    将费用作为属性而不是方法访问​​,该方法将使用已加载的费用集合并在 PHP 中汇总金额,而不是再次访问数据库。

    【讨论】:

    • 很棒的答案,我什至知道toArray 或 JSON 响应,因为我上周已经查过了。刚刚忘记了,谢谢也很高兴了解其他内容!
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 2023-02-02
    • 2015-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多