在Laravel Eloquent模型中停止'with'属性递归

时间:2017-09-19 15:50:59

标签: php laravel eloquent

在Laravel中假设两个雄辩模型 - userlocation

用户:

class User extends Model
{    
    /**
     * Relations that should be automatically loaded.
     *
     * @var array
     */
    public $with = [
        'locations'
    ];

    /**
     * Returns relation to the locations table.
     */
    public function locations() {
        return $this->belongsTo('App\Entities\Location');
    }
}

位置:

class Location extends Model
{    
    /**
     * Relations that should be automatically loaded.
     *
     * @var array
     */
    public $with = [
        'users'
    ];

    /**
     * Returns relation to the users table.
     */
    public function users() {
        return $this->hasMany('App\User');
    }
}

正如您所看到的,它们都具有公共属性with - 因为这些模型正在推动API,我希望用户始终返回其位置和位置总是返回其用户列表。

但是,正如我认为可能发生的那样,由于(我认为)递归导致请求超时。换句话说,该位置加载其用户,然后加载他们的位置,然后加载他们的用户,等等。

Laravel有没有办法强迫它进入正在进行“初始加载”的同一模型?

我应该提到user还有另一个关系profile,我希望在每个查询中加载它。因此,例如,如果有一种方法可以在某个“深度”之后简单地杀死with急切加载,那就不会这样做了。

编辑:我 意识到我可以使用User::with('location')->find();来加强关系,但是这个解决方案要求我在任何地方使用额外的代码我我正在检索用户。我正在寻找一种解决方案,让我始终自动加载关系。

2 个答案:

答案 0 :(得分:1)

它会产生一个无限循环的加载,例如你调用User现在它正在加载Location但是当加载Location时它再次调用它User它已被加载并且正在进行相同的加载过程,因此它会产生一个甚至没有破坏的循环。这就是为什么它会给出错误

你可以这样做

User::with('location')->find(..) // or get or any

答案 1 :(得分:0)

您可以解决此问题,只需将其他模型放在belongsTo方法中即可。

  1. 创建新的空JustLocation模型扩展了Location模型。
  2. 在JustLocation模型中设置protected $with = [];
  3. 在用户模型中将return $this->belongsTo('App\Entities\Location');更改为return $this->belongsTo('App\Entities\JustLocation');