Laravel减少查询和理解附录

时间:2018-07-12 15:07:02

标签: php laravel

我有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"
    ]

我认为我使用的是错误的/不理解它。任何对此的解释都将有所帮助。

1 个答案:

答案 0 :(得分:2)

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


警告::您不应命名更改者费用,因为这会与您的费用关系发生冲突。


在这种情况下,快速加载关系不会执行任何操作,因为您是在mutator中查询关系,而不是访问现有的关系集合。

如果您打算始终渴望加载费用,则应该更改

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

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

将费用作为属性访问,而不是将使用加载的费用集合并以PHP求和的方法,而不是再次访问数据库。