【问题标题】:Can I eager/lazy load an attribute in Laravel?我可以在 Laravel 中急切/懒惰地加载属性吗?
【发布时间】:2017-07-14 15:56:55
【问题描述】:

我知道我可以在 Laravel 中急切或延迟加载关系。我也知道关系对象基本上是变相的查询对象,调用$user->load('teams') 会执行该查询并将其添加到 $user 对象中(即使我不知道具体如何。)

假设我有一个 User 从 cmets 获得积分。要在数据库调用中获取用户的积分,我会执行如下操作:

SELECT `user_id`, sum(`points`) AS `total_points` FROM `user_comments` where `id` = ?

如果我想一次性加载它们,我会运行这个查询:

SELECT `users`.*, sum(`user_comments`.`points`) AS `total_points`
FROM `users` LEFT JOIN `user_points` ON `users`.`id` = `user_comments`.`user_id`
GROUP BY `users`.`id`

我想使用 Laravel 来完成这些任务。我希望喜欢写这样的东西

User::where('age', '>', 40)->with('total_points')->get();

并像这样访问值

$user->total_points

同时加载用户及其总分。我希望可能有很多很多记录,并且不想在每次有用户时都调用数据库连接查询。如果我只需要他们的总分值,我也不希望自己为每个用户加载所有 cmets。

有没有办法在 Laravel 中使用关系构建器来完成这项工作?

【问题讨论】:

    标签: php laravel-5 relationship eager-loading


    【解决方案1】:

    在您的用户模型中建立一种关系,如下所示

    public function total_points() {
            return $this->hasOne('user_comments')
                ->selectRaw('sum(points) as points, user_id')
                ->groupBy('user_id');
        }
    

    然后在控制器中执行此操作

    $user = User::where('age', '>', 40)->with('total_points')->get();
    

    【讨论】:

    • 这行得通!一旦我开始工作,我添加了一个 $appends 属性来检查关系是否已加载并获取值。
    • 但是如果是属性就不行了!我该怎么办?
    最近更新 更多