From 7315200531e6aee0547428444e4e20d734611878 Mon Sep 17 00:00:00 2001 From: Andrey Helldar Date: Sat, 22 Jun 2024 19:08:38 +0300 Subject: [PATCH] Fixed eager loading --- src/HasTranslations.php | 22 +++++++++++++++---- testbench.yaml | 1 + tests/Unit/Models/GetTest.php | 13 +++++++++++ .../app/Providers/AppServiceProvider.php | 21 ++++++++++++++++++ workbench/bootstrap/cache/services.php | 14 +++++++----- 5 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 workbench/app/Providers/AppServiceProvider.php diff --git a/src/HasTranslations.php b/src/HasTranslations.php index 05b1746..bc416e4 100644 --- a/src/HasTranslations.php +++ b/src/HasTranslations.php @@ -4,7 +4,6 @@ namespace LaravelLang\Models; -use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Arr; @@ -21,6 +20,8 @@ use LaravelLang\Models\Services\Relation; use function app; +use function array_merge; +use function array_unique; use function filled; use function in_array; use function is_iterable; @@ -45,11 +46,14 @@ protected static function translationModelName(): string return static::class . Config::shared()->models->suffix; } + public function initializeHasTranslations(): void + { + $this->with = array_unique(array_merge($this->with, ['translations'])); + } + public function translations(): HasMany { - return $this->hasMany(static::translationModelName(), 'item_id')->afterQuery( - fn (Collection $items) => $items->keyBy('locale') - ); + return $this->hasMany(static::translationModelName(), 'item_id'); } public function hasTranslated(string $column, Locale|string|null $locale = null): bool @@ -150,6 +154,16 @@ public function setAttribute($key, $value): Model return parent::setAttribute($key, $value); } + public function setRelation($relation, $value): static + { + $this->relations[$relation] = match ($relation) { + 'translations' => $value->keyBy('locale'), + default => $value + }; + + return $this; + } + public function newInstance($attributes = [], $exists = false): static { $basic = Arr::except($attributes, $this->translatable()); diff --git a/testbench.yaml b/testbench.yaml index 0148cf4..81726ff 100644 --- a/testbench.yaml +++ b/testbench.yaml @@ -1,5 +1,6 @@ laravel: ./workbench providers: + - App\Providers\AppServiceProvider - LaravelLang\Config\ServiceProvider - LaravelLang\Locales\ServiceProvider - LaravelLang\Models\ServiceProvider diff --git a/tests/Unit/Models/GetTest.php b/tests/Unit/Models/GetTest.php index d265267..0862037 100644 --- a/tests/Unit/Models/GetTest.php +++ b/tests/Unit/Models/GetTest.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use App\Models\TestModel; use App\Models\TestModelTranslation; use LaravelLang\Models\Exceptions\AttributeIsNotTranslatableException; use LaravelLang\Models\Exceptions\UnavailableLocaleException; @@ -68,6 +69,18 @@ expect($model->getTranslation(FakeValue::ColumnTitle, FakeValue::LocaleCustom))->toBeNull(); }); +test('lazy loading', function () { + $model1 = fakeModel(main: 'Foo'); + $model2 = fakeModel(main: 'Bar'); + + TestModel::query()->get()->each( + fn (TestModel $model) => match ($model->getKey()) { + $model1->getKey() => expect($model->title)->toBe('Foo'), + $model2->getKey() => expect($model->title)->toBe('Bar'), + } + ); +}); + test('non-translatable attribute', function () { $key = fake()->word; diff --git a/workbench/app/Providers/AppServiceProvider.php b/workbench/app/Providers/AppServiceProvider.php new file mode 100644 index 0000000..febeef5 --- /dev/null +++ b/workbench/app/Providers/AppServiceProvider.php @@ -0,0 +1,21 @@ +lazyLoading(); + } + + protected function lazyLoading(): void + { + Model::preventLazyLoading(); + } +} diff --git a/workbench/bootstrap/cache/services.php b/workbench/bootstrap/cache/services.php index 816ba4f..9a0f575 100644 --- a/workbench/bootstrap/cache/services.php +++ b/workbench/bootstrap/cache/services.php @@ -23,9 +23,10 @@ 19 => 'Illuminate\\Translation\\TranslationServiceProvider', 20 => 'Illuminate\\Validation\\ValidationServiceProvider', 21 => 'Illuminate\\View\\ViewServiceProvider', - 22 => 'LaravelLang\\Config\\ServiceProvider', - 23 => 'LaravelLang\\Locales\\ServiceProvider', - 24 => 'LaravelLang\\Models\\ServiceProvider', + 22 => 'App\\Providers\\AppServiceProvider', + 23 => 'LaravelLang\\Config\\ServiceProvider', + 24 => 'LaravelLang\\Locales\\ServiceProvider', + 25 => 'LaravelLang\\Models\\ServiceProvider', ), 'eager' => array ( @@ -39,9 +40,10 @@ 7 => 'Illuminate\\Pagination\\PaginationServiceProvider', 8 => 'Illuminate\\Session\\SessionServiceProvider', 9 => 'Illuminate\\View\\ViewServiceProvider', - 10 => 'LaravelLang\\Config\\ServiceProvider', - 11 => 'LaravelLang\\Locales\\ServiceProvider', - 12 => 'LaravelLang\\Models\\ServiceProvider', + 10 => 'App\\Providers\\AppServiceProvider', + 11 => 'LaravelLang\\Config\\ServiceProvider', + 12 => 'LaravelLang\\Locales\\ServiceProvider', + 13 => 'LaravelLang\\Models\\ServiceProvider', ), 'deferred' => array (