【问题标题】:Eager load extra model attributes急切加载额外的模型属性
【发布时间】:2026-02-11 01:10:01
【问题描述】:

我正在使用 Eloquent 和 Laravel。

案例:我正在构建一个 API,其中有可能与资源的 include 关系。例如/api/teams?include=users 将为每个Team 添加User 模型。对于包含我使用Fractal 的关系的逻辑。所以我需要一些逻辑来确定必须包含哪些关系,这样我就可以为它创建一个优化的查询。

问题:当我想用相关的User 模型渲染Team 的集合时。我可以很好地加载模型。当我在 User 模型上有自定义属性时,问题就来了。这些将导致 N+1 查询问题,因为对于每个预先加载的团队,因为自定义属性的查询将针对每个模型执行。

示例代码:

// The Team model with the custom attribute
class Team extends Model {
    protected $appends = ['is_member'];

    public function getIsMemberAttribute() {
        $loggedUser = Auth::currentUser();

        $result = DB::table('team_user')
                        ->where('team_id', $this-id)
                        ->where('user_id', $loggedUser->id)
                        ->get();

        return !is_null($result);
    }
}

// The controller code
$team = Team::findOrFail($teamId);

// So this will return all the User models that belong to the Team.
// The problem is this will execute the query inside the getIsMemberAttribute() for every User model.
dd($team->users);

有解决这个问题的好模式吗?

【问题讨论】:

  • 提供一些代码。这会有所帮助
  • @JilsonThomas 添加了一些代码 ;)!

标签: php oop laravel eloquent


【解决方案1】:

您可以遍历 User 模型并查看其中一个模型是否与登录用户匹配。它比在数据库中查找更有效。

class Team extends Model {
    protected $appends = ['is_member'];

    public function getIsMemberAttribute() {
        $loggedUser = Auth::currentUser();

        foreach ($this->users as $user) {

            if ($user->id == $loggedUser->id) {
                return true;
            }
        }

        return false;
    }
}

【讨论】: