Skip to content

Commit

Permalink
Add a solution for lazy loading violations (#392)
Browse files Browse the repository at this point in the history
* wip

* wip

* Fix styling

Co-authored-by: freekmurze <[email protected]>
  • Loading branch information
freekmurze and freekmurze authored Jun 3, 2021
1 parent 50547f0 commit ec53dfe
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 42 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/php-cs-fixer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Fix style
uses: docker://oskarstark/php-cs-fixer-ga
with:
args: --config=.php_cs --allow-risky=yes
args: --config=.php_cs.php --allow-risky=yes

- name: Extract branch name
shell: bash
Expand Down
33 changes: 0 additions & 33 deletions .github/workflows/psalm.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ composer.lock
.phpunit.result.cache
tests/stubs/Controllers/GitConflictController.php
package-lock.json
.php-cs-fixer.cache

13 changes: 5 additions & 8 deletions .php_cs → .php_cs.php
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
<?php

$finder = Symfony\Component\Finder\Finder::create()
->notPath('bootstrap/*')
->notPath('storage/*')
->notPath('resources/view/mail/*')
->in([
__DIR__ . '/src',
__DIR__ . '/tests',
])
->name('*.php')
->notName('*.blade.php')
->notName('GitConflictController.php')
->ignoreDotFiles(true)
->ignoreVCS(true);

return PhpCsFixer\Config::create()
return (new PhpCsFixer\Config())
->setRules([
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'ordered_imports' => ['sortAlgorithm' => 'alpha'],
'ordered_imports' => ['sort_algorithm' => 'alpha'],
'no_unused_imports' => true,
'not_operator_with_successor_space' => true,
'trailing_comma_in_multiline_array' => true,
'trailing_comma_in_multiline' => true,
'phpdoc_scalar' => true,
'unary_operator_spaces' => true,
'binary_operator_spaces' => true,
Expand All @@ -33,6 +29,7 @@
'method_argument_space' => [
'on_multiline' => 'ensure_fully_multiline',
'keep_multiple_spaces_after_comma' => true,
]
],
'single_trait_insert_per_statement' => true,
])
->setFinder($finder);
2 changes: 2 additions & 0 deletions src/IgnitionServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use Facade\Ignition\SolutionProviders\DefaultDbNameSolutionProvider;
use Facade\Ignition\SolutionProviders\IncorrectValetDbCredentialsSolutionProvider;
use Facade\Ignition\SolutionProviders\InvalidRouteActionSolutionProvider;
use Facade\Ignition\SolutionProviders\LazyLoadingViolationSolutionProvider;
use Facade\Ignition\SolutionProviders\MergeConflictSolutionProvider;
use Facade\Ignition\SolutionProviders\MissingAppKeySolutionProvider;
use Facade\Ignition\SolutionProviders\MissingColumnSolutionProvider;
Expand Down Expand Up @@ -404,6 +405,7 @@ protected function getDefaultSolutions(): array
UndefinedPropertySolutionProvider::class,
MissingMixManifestSolutionProvider::class,
MissingLivewireComponentSolutionProvider::class,
LazyLoadingViolationSolutionProvider::class,
];
}

Expand Down
41 changes: 41 additions & 0 deletions src/SolutionProviders/LazyLoadingViolationSolutionProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Facade\Ignition\SolutionProviders;

use Facade\Ignition\Support\LaravelVersion;
use Facade\IgnitionContracts\BaseSolution;
use Facade\IgnitionContracts\HasSolutionsForThrowable;
use Illuminate\Database\LazyLoadingViolationException;
use Throwable;

class LazyLoadingViolationSolutionProvider implements HasSolutionsForThrowable
{
public function canSolve(Throwable $throwable): bool
{
if ($throwable instanceof LazyLoadingViolationException) {
return true;
}

if (! $previous = $throwable->getPrevious()) {
return false;
}

return $previous instanceof LazyLoadingViolationException;
}

public function getSolutions(Throwable $throwable): array
{
$majorVersion = LaravelVersion::major();

return [BaseSolution::create(
'Lazy loading was disabled to detect N+1 problems'
)
->setSolutionDescription(
'Either avoid lazy loading the relation or allow lazy loading.'
)
->setDocumentationLinks([
'Read the docs on preventing lazy loading' => "https://laravel.com/docs/{$majorVersion}.x/eloquent-relationships#preventing-lazy-loading",
'Watch a video on how to deal with the N+1 problem' => 'https://www.youtube.com/watch?v=ZE7KBeraVpc',
]),];
}
}
11 changes: 11 additions & 0 deletions src/Support/LaravelVersion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Facade\Ignition\Support;

class LaravelVersion
{
public static function major()
{
return substr(app()->version(), 0, 1);
}
}
43 changes: 43 additions & 0 deletions tests/Solutions/LazyLoadingViolationSolutionProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Facade\Ignition\Tests\Solutions;

use Exception;
use Facade\Ignition\SolutionProviders\LazyLoadingViolationSolutionProvider;
use Facade\Ignition\Tests\TestCase;
use Illuminate\Database\LazyLoadingViolationException;
use Illuminate\Foundation\Auth\User;

class LazyLoadingViolationSolutionProviderTest extends TestCase
{
public function setUp(): void
{
parent::setUp();

if (version_compare($this->app->version(), '8.0.0', '<')) {
$this->markTestSkipped();
}
}

/** @test */
public function it_can_solve_lazy_loading_violations()
{
$canSolve = app(LazyLoadingViolationSolutionProvider::class)
->canSolve(new LazyLoadingViolationException(new User(), 'posts'));

$this->assertTrue($canSolve);

$canSolve = app(LazyLoadingViolationSolutionProvider::class)
->canSolve(new Exception('generic exception'));

$this->assertFalse($canSolve);
}

public function it_can_provide_the_solution_for_lazy_loading_exceptions()
{
$solutions = app(LazyLoadingViolationSolutionProvider::class)
->getSolutions(new LazyLoadingViolationException(new User(), 'posts'));

$this->assertCount(1, $solutions);
}
}

0 comments on commit ec53dfe

Please sign in to comment.