laravel-5 - 急切加载 hasMany & BeingsTo(循环引用/无限循环)

标签 laravel-5 eloquent eager-loading

更新(解决方案)

  • 如果您需要 ->user来自 $image 之一的关系内$user->images ,然后 $user变量已经可用,因为您加载了 ->images从中!
  • 不要使用 protected $with Eloquent 属性(property)。这是一种反模式。
  • 相反,在需要的地方/时间按需明确地急切加载关系(注意:它不应该阻止您保持干燥!)
  • 如果您真的需要/想要,请参阅@nicksonyap 答案。它可以解决问题(我相信 - 未经测试)。

  • 原件

    我遇到了一个我认为很简单的问题:
  • 我有一个 User对象有很多 Image s
  • Image属于User ...(逆关系)

  • 我的问题是我想同时加载 images()User模型和 user()Image模型。为此,我只需设置一个 $with属性如文档中所述。

    我的 User模型:

    class User extends EloquentModel {
        protected $with = ['images'];
    
        public function images()
        {
            return $this->hasMany(Image::class);
        }
    }
    

    我的 Image模型:

    class Image extends EloquentModel {
        protected $with = ['user'];
    
        public function user()
        {
            return $this->belongsTo(User::class);
        }
    }
    

    但是在表演的时候:

    $user = User::find(203);
    

    这会导致无限循环(php 段错误)。一定有某种我无法找到的循环引用:
    [1]    85728 segmentation fault
    

    编辑 2016/02

    这是我发现的最简单的“解决方法”:

    // User.php
    public function setRelation($relation, $value)
    {
        if ($relation === 'images') {
            foreach ($value as $image) {
                $image->setUser($this);
            }
        }
        return parent::setRelation($relation, $value);
    }
    

    最佳答案

    有一个without()方法:https://laravel.com/api/5.8/Illuminate/Database/Eloquent/Builder.html#method_without
    放置without()在关系的双方都奏效了。

    class Property extends EloquentModel {
        protected $with = ['images'];
    
        public function images()
        {
            return $this->hasMany(Image::class)->without('property');
        }
    }
    
    class Image extends EloquentModel {
        protected $with = ['property'];
    
        public function property()
        {
            return $this->belongsTo(Property::class)->without('images');
        }
    
        public function getAlt()
        {
            return $this->property->title;
        }
    }
    
    更新:
    即使使用 without()轻松避免无限循环问题,通过多年的 Laravel 经验,我意识到设置 $with 是不好的做法。在模型中,因为它会导致始终加载关系。因此导致循环引用/无限循环
    相反,始终使用 with()明确指定 急切加载必要的关系,无论多么必要(关系的关系)
    例如:
    $user = User::with('images' => function ($query) {
                $query->with('property' => function ($query) {
                    $query->with('deeperifneeded' => function ($query) {
                        //...
                    });
                });
            ]);
    
    注意:可能需要删除 without()

    关于laravel-5 - 急切加载 hasMany & BeingsTo(循环引用/无限循环),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34995187/

    相关文章:

    php - 我的表单请求有什么问题导致简单的验证规则不起作用?

    php - 一般错误 : 1366 Incorrect string value in Laravel/Mysql

    php - Laravel 5 从 Laravel 安装外部加载 View

    mysql - Laravel Eloquent 多个 AND/OR 语句

    php - 如何在 Laravel 4 的 Eloquent ORM 中使用 IN 或 Nesting of queires

    php - Laravel `with` 问题

    mysql - 优化数据库更新

    php - 我想使用从 Laravel 中的另一个表生成的 id 从表中打印列的值

    ruby-on-rails - 子类上的急切加载关联

    php - Laravel Eloquent 嵌套关系仅返回第一个元素的数据