Last active
July 11, 2016 05:40
-
-
Save patrickguevara/29379ef87c8e76ff30f6348e00e7db40 to your computer and use it in GitHub Desktop.
A helper Trait for Laravel Eloquent Models - https://metricloop.com/blog/how-to-let-your-laravel-eloquent-models-find-themselves?utm_source=github_gist&utm_medium=blog&utm_content=post_17&utm_campaign=github_gists
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Traits; | |
use Illuminate\Database\Eloquent\ModelNotFoundException; | |
trait CanResolveSelf | |
{ | |
/** | |
* Resolves model regardless of given identifier. | |
* | |
* @param $model | |
* @param bool $withTrashed | |
* @return mixed | |
* @throws \Exception | |
*/ | |
public static function resolveSelf($model, $withTrashed = false) | |
{ | |
$className = get_called_class(); | |
if(is_null($model)) { | |
return null; | |
} | |
if(!$model instanceof $className) { | |
if(is_numeric($model)) { | |
try { | |
$model = $className::when($withTrashed, function ($query) { | |
return $query->withTrashed(); | |
})->findOrFail($model); | |
} catch (ModelNotFoundException $e) { | |
throw new \Exception($className . ' not found with the given ID.'); | |
} | |
} else { | |
try { | |
$model = $className::when($withTrashed, function ($query) { | |
return $query->withTrashed(); | |
})->where('slug', $model)->firstOrFail(); | |
} catch (ModelNotFoundException $e) { | |
throw new \Exception($className . ' not found with the given slug.'); | |
} | |
} | |
} | |
return $model; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Foundation\Testing\DatabaseMigrations; | |
class CanResolveSelfTraitTest extends TestCase | |
{ | |
use DatabaseMigrations; | |
/** @test */ | |
public function if_given_itself_should_return_itself() | |
{ | |
$posts = factory(App\Post::class, 2)->create(); | |
$post = App\Post::findOrFail(1); | |
$result = App\Post::resolveSelf($post); | |
$this->assertEquals($post, $result); | |
} | |
/** @test */ | |
public function if_given_null_should_return_null() | |
{ | |
factory(App\Post::class, 2)->create(); | |
$result = App\Post::resolveSelf(null); | |
$this->assertNull($result); | |
} | |
/** @test */ | |
public function if_given_id_should_return_appropriate_model() | |
{ | |
factory(App\Post::class, 2)->create(); | |
$post = App\Post::findOrFail(1); | |
$result = App\Post::resolveSelf(1); | |
$this->assertEquals($post, $result); | |
} | |
/** @test */ | |
public function if_given_text_should_return_appropriate_model() | |
{ | |
factory(App\Post::class, 2)->create(); | |
$post = App\Post::findOrFail(1); | |
$result = App\Post::resolveSelf($post->slug); | |
$this->assertEquals($post, $result); | |
} | |
/** | |
* @test | |
* @expectedException \Exception | |
* @expectedExceptionMessage App\Post not found with the given ID. | |
*/ | |
public function should_throw_exception_if_id_not_found() | |
{ | |
factory(App\Post::class, 2)->create(); | |
App\Post::resolveSelf(3); | |
} | |
/** | |
* @test | |
* @expectedException \Exception | |
* @expectedExceptionMessage App\Post not found with the given slug. | |
*/ | |
public function should_throw_exception_if_slug_not_found() | |
{ | |
factory(App\Post::class, 2)->create(); | |
App\Post::resolveSelf('foo'); | |
} | |
/** @test */ | |
public function returns_appropriate_model_from_id_even_if_it_was_soft_deleted() | |
{ | |
factory(App\Post::class, 2)->create(); | |
$post = App\Post::findOrFail(1); | |
$post->delete(); | |
$result = App\Post::resolveSelf(1, $withTrashed = true); | |
$this->assertEquals(App\Post::withTrashed()->findOrFail(1), $result); | |
$this->assertTrue($result->trashed()); | |
} | |
/** @test */ | |
public function returns_appropriate_model_from_slug_even_if_it_was_soft_deleted() | |
{ | |
factory(App\Post::class, 2)->create(); | |
$post = App\Post::findOrFail(1); | |
$post->delete(); | |
$result = App\Post::resolveSelf($post->slug, $withTrashed = true); | |
$this->assertEquals(App\Post::withTrashed()->findOrFail(1), $result); | |
$this->assertTrue($result->trashed()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment