Bloomanity's avatar

onDelete('cascade')

I have 2 models: Lesson and Module with a manyToMany relationship; There is a coresponding lesson_module pivot table:

Schema::create('lesson_module', function (Blueprint $table) {
            $table->integer('lesson_id')->unsigned();
            $table->foreign('lesson_id')->references('id')->on('lessons')->onDelete('cascade');

            $table->integer('module_id')->unsigned();
            $table->foreign('module_id')->references('id')->on('modules')->onDelete('cascade');

            $table->integer('order')->unsigned()->default(0);

            $table->timestamps();
        });

If I delete a module it should remove the corresponding records in the pivot table, right?

It doesn't :)

I'm using Sqlite and testing this with PHPUnit.

Am I doing anything wrong?

The test

/** @test */
    public function it_successfully_deletes_a_module()
    {
        $module = factory(Module::class)->create();
        $module2 = factory(Module::class)->create();

        $lessons = $this->makeAndPersistVideoLessons(2);

        $module->lessons()->attach([1, 2]);

        $this->visit(route('admin.modules.show', $module->slug))
                ->press('Sterge')
                ->seePageIs(route('admin.modules.index'))
                ->see('Modulul a fost sters!');

        $this->notSeeInDatabase('modules', $module->attributesToArray())
                ->seeInDatabase('modules', $module2->attributesToArray())
                ->notSeeInDatabase('lesson_module', ['module_id' => $module->id, 'lesson_id' => 1])
                ->notSeeInDatabase('lesson_module', ['module_id' => $module->id, 'lesson_id' => 2])
                ->seeInDatabase('lessons', ['id' => 1])
                ->seeInDatabase('lessons', ['id' => 2])
                ->seeInDatabase('videos', ['id' => 1])
                ->seeInDatabase('videos', ['id' => 2]);
    }

The Event Handler to remove the lesson

/**
     * Handle the event.
     *
     * @param  ModuleRemoveRequested  $event
     * @return void
     */
    public function handle(ModuleRemoveRequested $event)
    {
        $id = $event->id;

        $module = Module::findOrFail($id);

        // $module->lessons()->detach();

        $module->delete();
        event(new ModuleWasDeleted($module));
    }

If I don't comment out the detach() the test returns green.

Did I understand the onDelete('cascade') functionallity wrong?

0 likes
4 replies
Thijmen's avatar

SQLite doesn't support the cascading onDelete.

bobbybouwmann's avatar
Level 88

@Bloomanity Add this to the boot() method in your App\Providers\AppServiceProvider

if (DB::connection() instanceof \Illuminate\Database\SQLiteConnection) {
    DB::statement(DB::raw('PRAGMA foreign_keys=1'));
}
2 likes

Please or to participate in this conversation.