Skip to content

Commit

Permalink
Merge pull request #3 from enginedigital/feature/eager-loading
Browse files Browse the repository at this point in the history
Added: support for eager loading relationships on notes
  • Loading branch information
james2doyle authored Feb 9, 2022
2 parents efc8398 + 2f6d84c commit 9ef0eed
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ return [
'author_model' => null, // App\Models\User::class
'author_resolver' => null, // a class that uses `__invoke` or a container function to get the id of the current user
'cache_time' => null, // cache time in seconds
'load_with' => [], // which note relationships to eager load. Example: ['author', 'author.profile', 'author.roles'] or only specific columns ['author:id,name']
];
```

Expand Down
1 change: 1 addition & 0 deletions config/model-notes.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@
'author_model' => null, // App\Models\User::class
'author_resolver' => null, // a class that uses `__invoke` or a container function to get the id of the current user
'cache_time' => null, // cache time in seconds
'load_with' => [], // which note relationships to eager load. Example: ['author', 'author.profile', 'author.roles'] or only specific columns ['author:id,name']
];
2 changes: 1 addition & 1 deletion database/migrations/create_model_notes_table.php.stub
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ return new class extends Migration
->onDelete('cascade');
}

/** @var Illuminate\Database\Eloquent\Model|null */
$authorModel = $config['author_model'] ? app($config['author_model']) : false;

if ($authorModel) {
Expand All @@ -46,7 +47,6 @@ return new class extends Migration

public function down()
{
// $table->dropForeign('posts_user_id_foreign');
Schema::dropIfExists('notes');
}
};
13 changes: 10 additions & 3 deletions src/HasAllNotesAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,15 @@ public function getAllNotesAttribute()
/** @var int|null */
$cacheTimeInSeconds = config('model-notes.cache_time');

return $cacheTimeInSeconds ? cache()->remember($this->{$this->getKeyName()} . '-notes', $cacheTimeInSeconds, function () {
return $this->notes()->get();
}) : $this->notes()->get();
/** @var string[] */
$eagerLoad = config('model-notes.load_with', []);

if (is_null($cacheTimeInSeconds)) {
return $this->notes()->with($eagerLoad)->get();
}

return cache()->remember($this->{$this->getKeyName()} . '-notes', $cacheTimeInSeconds, function () use ($eagerLoad) {
return $this->notes()->with($eagerLoad)->get();
});
}
}
70 changes: 70 additions & 0 deletions tests/NoteAuthorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace EngineDigital\Note\Tests;

use EngineDigital\Note\HasAllNotesAttribute;
use EngineDigital\Note\HasNotes;
use EngineDigital\Note\Note;
use Illuminate\Database\Eloquent\Model;

class FakeUserWithNotes extends Model
{
use HasNotes;
use HasAllNotesAttribute;

protected $table = 'users';
protected $fillable = ['name'];
protected $appends = ['all_notes'];
}

class NoteAuthorTest extends TestCase
{
public $user;

public function setUp(): void
{
parent::setUp();

config()->set('model-notes.cache_time', null);
config()->set('model-notes.load_with', ['author']);

config()->set('model-notes.author_model', FakeUserWithNotes::class);
app()->bind('App\\UserResolver', function () {
return function () {
return FakeUserWithNotes::first()->id;
};
});

config()->set('model-notes.author_resolver', 'App\\UserResolver');

$createUser = require __DIR__ . '/create_users_table.php';
$createUser->up();

$createNotes = require __DIR__ . '/../database/migrations/create_model_notes_table.php.stub';
$createNotes->up();

$this->user = FakeUserWithNotes::create([
'name' => 'The Author',
]);
}

/** @test */
public function notes_can_eager_load_related_data()
{
$anotherUser = FakeUserWithNotes::create([
'name' => 'Someone Else',
]);

$note = Note::create([
'note' => 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
// 'author_id' => $this->user->id, // should be set by the model booted method
'model_type' => FakeUserWithNotes::class,
'model_id' => $anotherUser->id,
]);

$first_note = $anotherUser->fresh()->all_notes[0]->toArray();

// $this->user created the note and should have their details loaded on the notes created on $anotherUser
$this->assertEquals($this->user->name, $first_note['author']['name']);
}
}

0 comments on commit 9ef0eed

Please sign in to comment.