Laravel模型关联超时求助:Notes与Users关联致脚本崩溃
问题排查与解决方案
看起来你遇到的是关联参数错误+循环加载导致的脚本崩溃,咱们一步步来理清楚:
首先,修正关联参数的错误
你的User模型里created_notes方法的hasMany参数顺序搞反了!
hasMany的参数规则是:hasMany(关联模型类名, 关联模型中的外键字段, 当前模型的主键字段)。你之前写的return $this->hasMany("App\Note", "id", "user_id_created")把外键和本地键搞反了,正确的写法应该是:
class User { public function notes(){ // 这个是对的,默认关联notes表的user_id字段 return $this->hasMany("App\Note"); } public function created_notes(){ // 修正:外键是notes表的user_id_created,指向当前User的id return $this->hasMany("App\Note", "user_id_created"); // 第三个参数id可以省略,因为Laravel默认会用当前模型的主键 } }
核心问题:无限循环加载
你在Note模型里设置了protected $with = ['created_by'],这会导致循环嵌套查询:
- 当加载User模型时,如果触发了
created_notes关联,会加载对应的Note集合 - 每个Note又会自动加载
created_by关联(也就是User模型) - 加载的User模型又会触发
created_notes关联,再次加载Note...
这种无限循环会直接耗尽服务器内存,导致脚本超时崩溃。
解决方案
方案一:移除自动加载,改用按需加载
最稳妥的方式是去掉Note模型里的$with = ['created_by'],在需要获取创建者的时候手动加载关联:
class Note { // 删掉$with配置,避免自动触发关联 public function created_by(){ // 这个关联的参数是对的,不用改 return $this->belongsTo("App\User", "user_id_created", "id"); } // 可以额外加一个关联,对应notes表的user_id(笔记所属用户) public function owner(){ return $this->belongsTo("App\User", "user_id"); } }
使用时手动指定加载关联:
// 获取单条笔记及其创建者 $note = Note::with('created_by')->find(1); // 获取用户及其创建的笔记(不会触发循环,因为Note不会自动加载created_by) $user = User::with('created_notes')->find(1);
方案二:保留自动加载,阻断循环
如果你确实需要自动加载created_by,可以在User的created_notes关联里排除Note的created_by加载:
class User { public function created_notes(){ return $this->hasMany("App\Note", "user_id_created")->without('created_by'); } }
这样当加载User的created_notes时,每个Note不会自动加载created_by,循环就被打断了。
内容的提问来源于stack exchange,提问作者Connor Simpson
相关产品推荐
相关产品推荐

