Laravel Pro tips: Part I

In this content, having a few useful tips for develop project with laravel.

Route group

Problem

Routes are too many and mix in one file.

Route::prefix('admin/posts')->group(function() {
Route::get('/', 'PostController@index');
Route::get('create', 'PostController@create');
Route::get('/', 'PostController@store');
Route::get('{post}', 'PostController@show');
});

Better

Using __DIR__ or base_path() and assign to $routes

Route::prefix('admin/posts')->group(__DIR__ . '/admin/posts.php');
// or
Route::prefix('admin/posts')->group(base_path('routes/admin/posts.php'));

Auth

Arguments

Using arguments of boolean to define what you need.

Auth::routes([
'reset' => true,
// Eloquent instance of MustVerifyEmail
'verify' => true,
'register' => true,
]);

FormRequest validate fails to redirect

Redirect with validation fails.

Customize redirect to somewhere with 3 ways.

class PostRequest extends FormRequest
{
// redirect by uri.
protected $redirect = 'hello';

// redirect by route.
protected $redirectRoute = 'hello';

// redirect by controller action.
protected $redirectAction = 'PostController@index';

More tip!

Assign parameters to redirect path or uri

class PostRequest extends FormRequest
{
public function __construct()
{
$this->redirect = route('hello', 1);
}

Eloquent property with default value

Problem

If you call the relationship does not exist, but you need to prevent error and display default

class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}

// user_id = 55123 (does NOT exist)
$post = Post::find(1);
// get property 'name' of non-object
$post->user->name;

Better

Using with default in belongsTo relation and set a default value.

class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class)
->withDefault([
'name' => 'Guest Author',
]);
}

// user_id = 55123 (does NOT exist)
$post = Post::find(1);
// no error and display 'Guest Author'
$post->user->name;

Exception handle render

Before handle render

Should instance of specific exception and render specific view or data.

// application throw exception.
throw new \App\Exceptions\CartIsEmpty;

// Handler.php
public function render($request, Exception $exception)
{
if ($exception instanceof CartIsEmpty) {
return view('errors.empty')->with('message', 'Cart is empty!');
}

return parent::render($request, $exception);
}

Making exception via command and option

Using option to set render method.

$ php artisan make:exception CartIsEmpty  --render

Better

Handling in exception and rendering.

// application throw exception.
throw new \App\Exceptions\CartIsEmpty;

// CartIsEmpty.php
class CartIsEmpty extends Exception
{
public function render($request)
{
return view('errors.empty')->with('message', 'Cart is empty!');
}

Route is in condition

Before

Seen good, but so long and redundancy.

<li class="{{ (request()->segment(2) == 'cities') ? 'active' : '' }}">
<li class="{{ (strpos(Route::currentRouteName(), 'admin.cities') == 0) ? 'active' : '' }}">

Better

Using route is to define it and do the same thing.

<li class="{{ (request()->is('admin/cities')) ? 'active' : '' }}">
<li class="{{ (request()->is('admin/cities*')) ? 'active' : '' }}">
Route::currentRouteNamed('admin*')
request()->route()->named('admin*')

Preview mail content

Better

Check mail content with html page without sending.

$ php artisan make:mail Welcome

// preview
Route::get('mail', function () {
return new \App\Mail\Welcome;
});

Column type with migration

Better

laravel.com/docs/5.7/migrations#columns

$table->geometry('positions');
$table->geometryCollection('positions');
$table->ipAddress('visitor');
$table->macAddress('device');
$table->uuid('id');
$table->unsignedInteger('votes');
$table->year('birth_year');

Eloquent increment / decrement

Better

Using increment and decrement to calculate column of numbers.

Post::find($post_id)->increment('view_count');
Post::find($post_id)->decrement('view_count');

Counting binding

Better

laravel.com/docs/5.7/eloquent-relationships#counting-related-models

// before
$post = App\Post::find(1);
$comment_count = $post->comments->count();

//better
$post = App\Post::whereId(1)->withCount('comments')->get();
// auto assign `$post->comments_count`

Customizing Route Key Name

Problem

The user be select by name, not to do by id. laravel.com/docs/5.7/routing#route-model-binding

class User extends Authenticatable
{
public function getKeyName()
{
return 'name';
}

New features

array_wrap

laravel-news.com/array_wrap

// before
$posts = in_array($posts) ? $posts : [$posts];

// same as
$posts = array_wrap($posts);

asset_url

laravel-news.com/laravel-5-7-14

// config/app.php
'asset_url' => 'https://cdn.example.com',

Bouns

stateless(no sessions or cookies), building with stateless API.

Auth::once([
'email' => '44@tt.com',
'password' => '44@tt.com',
])

To be continued.