20 un-known gems of laravel

20 Un-known Gems of Laravel

Spread the love

Laravel is full of hidden gems that I have discovered during working on different tasks. Some of these gems were less-known or un-documented features, functions parameters and hacks. In this blog post I will share those hidden gems with you, let’s get started.

01: Touching Parent Timestamps.

As the heading suggests, you can touch the timestamps of parent when the child model is updated. For example, two entities Post and Comment which have parent child relationship. For example, when a Comment model is updated you may want to touch, or update updated_at timestamp of parent model. Eloquent makes it easy, just add a touches property containing the names of relationships to the child model.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    /**
     * All of the relationships to be touched.
     *
     * @var array
     */
    protected $touches = ['post'];

    /**
     * Get the post that the comment belongs to.
     */
    public function post()
    {
        return $this->belongsTo('App\Post');
    }
}

02: Eager Loading with Exact Columns.

During Eager Loading you can specify exact columns you want to get from the relationship.

$users = App\Book::with('author:id,name')->get();

03: Authenticate a User for Single Request Auth::once().

You may use Auth::once(), to authenticate a user for single request, no sessions of cookies will be utilized. It means this method may be helpful in building stateless API.

if (Auth::once($credentials)) {
    //
}

04: Redirect to Controller Method with Parameters.

You can use redirect()  for not only for specific URL or routes, but to specific method of specific Controller with parameters.

return redirect()->action('SomeController@method',    ['param' => $value]);

05: How to Avoid Errors in Relationships Using withDefault().

When a relationship is called, and it doesn’t exist you will going to get a fatal error for example $post->user->name, to avoid it use withDefault().

/**  * Get the author of the post.  */ 
public function user() 
{     
return $this->belongsTo('App\User')->withDefault(); 
}

06: Two Level $loop Variable in Blade.

In Blade’s foreach you can use $loop variable even in two-level loop to reach parent variable.

@foreach ($users as $user)     
 @foreach ($user->posts as $post)         
    @if ($loop->parent->first)             
       This is first iteration of the parent loop.         
   @endif     
 @endforeach 
@endforeach

07: Modify Query Results.

After execution of Eloquent query, you can modify the rows by using map().

$users = User::where('role_id', 1)->get()->map(function (User $user) {
    $user->some_column = some_function($user);
    return $user;
});

08: dd() With Ease.

Instead of doing dd($result);  you can do $test->dd();  directly at the end of your Eloquent sentence.

// Instead of
$users = User::where('name', 'Taylor')->get();
dd($users);
// Do this
$users = User::where('name', 'Taylor')->get()->dd();

09: Use hasMany to saveMany.

If you have hasMany() relationship and from the parent object you want to saveMany() child objects, you can do it by saveMany().

$post = Post::find(1);
$post->comments()->saveMany([
    new Comment(['message' => 'First comment']),
    new Comment(['message' => 'Second comment']),
]);

10: Specify Columns in Model::all().

When using Eloquent’s User::all() you can specify which columns to return.

$users = User::all(['id', 'name', 'email']);

11: @auth of Blade.

Instead of if-statement to check whether user is authenticated or not, you can use @auth directive.

Typical way:

@if(auth()->user())     // The user is authenticated. @endif 

Shorter:

@auth    
 // The user is authenticated. 
@endauth

12: Preview Email without Sending Them.

If you are using mailables to send emails, you can view your emails without sending them.

Route::get('/mailable', function () {
    $invoice = App\Invoice::find(1);
    return new App\Mail\InvoicePaid($invoice);
});

13: hasMany with Specific Checks.

In Eloquent hasMany() relationships you can filter out records that have n amount of children records.

// Author -> hasMany(Book::class) 
$authors = Author::has('books', '>', 5)->get();

14: Soft Deletes Restore Multiple.

Where you are using soft deletes, you can restore multiple rows at once.

Post::withTrashed()->where('author_id', 1)->restore();

15: Migration Columns with Time zones.

Do you know migrations not only have timestamps() but also  timestampsTz()  for the time zone.

Schema::create('employees', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('email');
    $table->timestampsTz();
});

16: Does a View Exists ?.

Do you know you can check whether a view exists or not ?

if (view()->exists('custom.page')) {
// Load the view
}

17: Route Group within a Group.

In routes you can create a group with a route group and can also attach specific middleware.

Route::group(['prefix' => 'account', 'as' => 'account.'], function() {
    Route::get('login', 'AccountController@login');     
    Route::get('register', 'AccountController@register');
    Route::group(['middleware' => 'auth'], function() {         
        Route::get('edit', 'AccountController@edit');     
    });
});

18: Eloquent Where Date Methods.

In the Eloquent check the dates with functions whereDay() , whereMonth() , whereYear() , whereDate() , whereTime().

$products = Product::whereDate('created_at', '2018-01-31')->get(); 
$products = Product::whereMonth('created_at', '12')->get(); 
$products = Product::whereDay('created_at', '31')->get(); 
$products = Product::whereYear('created_at', date('Y'))->get(); 
$products = Product::whereTime('created_at', '=', '14:13:58')->get();

19: Apply orderBy() on Eloquent Relationships.

You can specify orderBy() directly in your Eloquent relationships.

public function products()
{
    return $this->hasMany(Product::class);
}

public function productsByName()
{
    return $this->hasMany(Product::class)->orderBy('name');
}

20: Unsigned Integer.

For foreign key migrations instead of using integer() use unsignedInteger()  or integer()->unsigned() other wise you will get errors.

Schema::create('employees', function (Blueprint $table) {     
    $table->unsignedInteger('company_id');     
    $table->foreign('company_id')->references('id')->on('companies');     
});

26 thoughts to “20 Un-known Gems of Laravel”

    1. I totally agree with you dear get() is better than all, but less people know that we can select columns in all as well so that’s why I have considered all() rather than get().

    2. all() referes to all records in the database versus selected ones when you use some where() clauses, not to all the attributes for record/s

  1. Great article! Afaik this is intended to exclude complicated alternatives and stick with normal way like before in 4.x version of laravel.

    Developers adjusted a lot when psr4 came in.

    Have you checked the selectRaw, whereRaw, selectSub and many more inside eloquent builder? Those things ain’t documented, nor boot{YourMethod} custom magic method.

    There are lots of missing/undocumented and will always be intended only for advanced laravel devs.

  2. Thanks for your mаrvelous posting! I truly enjoyed reading it,
    уou might be a great author.I will make sure to Ƅookmark
    your blog and will come back later in life.
    I want to encourage continue your great joƅ, have a nice day!

  3. Eager loading with exact fields … this is definitely going to reduce my network traffic because I use eager loaded models for serverside Datatables extensively …. 👍🏻👍🏻

  4. 19
    public function products()
    {
    return $this->hasMany(Product::class);
    }
    public function productsByName()
    {
    return $this->products()->orderBy(‘name’);
    }

Comments are closed.