【问题标题】:hasMany timing out when retrieving belongsTo models检索 belongsTo 模型时 hasMany 超时
【发布时间】:2018-05-16 02:37:16
【问题描述】:

从这个 Laravel 5.1 文档看来,我可以在 HasMany 关系上使用以下内容覆盖 foreign_keylocal_key

return $this->hasMany('App\Comment', 'foreign_key', 'local_key');

我将belongsTo 模型NpcTarget 中的外键从npc_id 更改为npc_id_fk。因此,我将关系更改为:

public function npc()
{                            
    return $this->belongsTo(Npc::class, 'npc_id_fk', 'id');
}

npc_id_fk引用npc的外键id,idnpc中列的实际名称。

我的目标是加载quest 及其task 及其npc 及其npctarget。运行我自己的查询按预期工作:

select n.id, nt.id from npcs n inner join npcstarget nt on (n.id = nt.npc_id_fk);

问题:鉴于以下关系,当我运行此程序时,浏览器超时。我得到错误:

QueryCollector.php 第 0 行中的 FatalErrorException:

最大执行时间超过 30 秒

但是,如果我更改为 return $this->belongsTo(Npc::class, 'npc_id_fk', 'npc_id');,它将运行查询 where "npcstarget"."npc_id_fk" in ('')。为什么浏览器会超时?


使用定义为$this->belongsTo(Npc::class, 'npc_id_fk', 'npc_id');NpcTarget 关系命中以下路由:

Route::get('/quest', function () {
    $quest = Quest::findOrFail(1)->get();
});

我得到 DebugBar 输出:

select * from "quests" where "quests"."id" = '1' limit 1
select * from "tasks" where "tasks"."quest_id" in ('1')
select "npcs".*, "task_npcs"."task_id" as "pivot_task_id", "task_npcs"."npc_id" as "pivot_npc_id" from "npcs" inner join "task_npcs" on "npcs"."id" = "task_npcs"."npc_id" where "task_npcs"."task_id" in ('1', '2', '3')
select * from "npcstarget" where "npcstarget"."npc_id_fk" in ('')

使用定义为$this->belongsTo(Npc::class, 'npc_id_fk', 'id');NpcTarget 关系命中同一条路由,它会超时且没有查询输出。

型号:

任务:

class Quest extends BaseModel
{
    protected $with = ['tasks'];

    public function tasks()
    {
        return $this->hasMany(Task::class);
    }
    ...
}

任务:

class Task extends BaseModel
{
    protected $with = ['npcs'];

    public function npcs()
    {
        return $this->belongsToMany(Npc::class, 'task_npcs');
    }
    ...
}

NPC:

class Npc extends BaseModel
{
    protected $with = ['npcstarget'];

    public function npcstarget()
    {
        return $this->hasMany(NpcTarget::class, 'npc_id_fk', 'id');
    }
}

NPC目标:

class NpcTarget extends Npc
{
    protected $table = 'npcstarget';

    public function npc()
    {
        // If this: Times out
        return $this->belongsTo(Npc::class, 'npc_id_fk', 'id');

        // If this: Shows above "where "npcstarget"."npc_id_fk" in ('')"
        return $this->belongsTo(Npc::class, 'npc_id_fk', 'npc_id');
    }
}

【问题讨论】:

    标签: sql laravel laravel-5.1 has-many belongs-to


    【解决方案1】:

    似乎错误是让NpcTarget 扩展Npc

    class NpcTarget extends Npc
    {
        protected $table = 'npcstarget';
    
        public function npc()
        {
            // If this: Times out
            return $this->belongsTo(Npc::class, 'npc_id_fk', 'id');
        }
    }
    

    将其更改为 class NpcTarget extends BaseModel 有效。

    我猜这是因为扩展 Npc 会在 NpcTarget 上调用另一个 with 查询,从而创建一个无限循环。

    我仍然想扩展父模型以获取它的一些属性。

    【讨论】:

    • 你试过用 Blackfire 分析它吗? npc_id_fk 有索引吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    相关资源
    最近更新 更多