热切加载对Laravel中的Model事件/引导有一些意想不到的副作用


Eager loading has some unexpected side effects on Model events/ booting in Laravel

我正在尝试创建一些测试。

这是我的测试班:

class ExampleTest extends TestCase {
    public function setUp()
    {
        parent::setUp();
        Artisan::call('migrate');
        $this->seed();
        Auth::loginUsingId(1);
    }
    public function testActionUpdateNew()
    {
        $action = new Action(Array());
        $action->save();
        var_dump($action->id);
        Action::with('reponses','contact','user','etudiant','entreprise','etude')->findOrFail($action->id);
    }
    public function testEtudes()
    {
        $etudes=Etude::all()->toArray();
        $this->assertCount(10, $etudes, "Nombre d'études incorrectes");
        $numEtudes=count($etudes);
        //Buggy part
        $etude= Etude::create(Array());
        var_dump($etude->id);
        $etudes=Etude::all()->toArray();
        $this->assertCount(11, $etudes, "Nombre d'études incorrectes");
        //10+1 should equal to 11 but it hasnt updated
    }
}

没有通过的测试是第二个:我计算出有说服力的对象练习集的数量,一开始是10,然后我向数据库中添加一个练习集(使用练习集::create()),对象就创建了,因为$etude->id给出了一个实数。然而,练习曲的编号并没有更新。

当我从Action中的热切加载中删除"练习曲"时,问题确实消失了::with('responses',…)

以下是Action类中的练习曲关系:

public function etude() {
    return $this->belongsTo('Etude');
}

你们知道laravel中的热切加载是否会有如此奇怪的行为吗?以及如何解决这个问题?

编辑

我发现用("tude")调用可以删除注册到Eloquent模型的事件:

练习的引导方法:

public static function boot()
{
    parent::boot();
    static::creating(function($etude)
        {
                       var_dump("creating etude"); //This doesn't get executed even when I run Etude::create(Array());
        }
    );
}

因此,如果我在testEtudes的开头添加Etude::boot(),它会再次起作用。这仍然很奇怪。

急切加载对事件或引导方法有任何影响吗?或者引导方法不是在每次测试后自动调用的?

在Laravel测试中,事件调度器在每次测试之间重置,但模型仍然只启动一次,因为它们过着相当独立的生活。这意味着在每次测试之间,模型侦听器都会被擦除,但永远不会重新注册。解决方案是不使用boot()来注册模型事件,而是将它们放在一个单独的文件中——服务提供商或app/start/global.php中包含的文件(app/events.php是一个常见的文件)。