hasMany在检索belongsTo模型时超时

时间:2018-05-16 02:37:16

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

在这个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 ('')。为什么浏览器超时?

点击以下路线,NpcTarget关系定义为$this->belongsTo(Npc::class, 'npc_id_fk', 'npc_id');

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 ('')

点击NpcTarget关系定义为$this->belongsTo(Npc::class, 'npc_id_fk', 'id');的相同路线时,它会超时而没有查询输出。

型号:

任务:

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');
    }
}

NpcTarget:

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');
    }
}

1 个答案:

答案 0 :(得分:0)

似乎错误是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会在with上调用另一个NpcTarget查询,从而产生无限循环。

我仍然希望扩展父模型以获得它的一些属性。