Laravel - find by custom column or fail

LaravelLaravel 4EloquentLaravel 5

Laravel Problem Overview


There's findOrFail() method which throws 404 if nothing was found, e.g.:

User::findOrFail(1);

How can I find an entity by custom column or fail, something like this:

Page::findBySlugOrFail('about');

Laravel Solutions


Solution 1 - Laravel

Try it like this:

Page::where('slug', '=', 'about')->firstOrFail();    
// or without the explicit '='
Page::where('slug', 'about')->firstOrFail();

Solution 2 - Laravel

Update: I'm currently using Laravel 6.9.0 and I confirm that @jeff-puckett is right. Where clause works fine. This is how it works on my tinker.

>>> \App\Models\User::findOrFail('123b5545-5adc-4c59-9a27-00d035c1d212');
>>> App\Models\User
     id: "123b5545-5adc-4c59-9a27-00d035c1d212",
     name: "John",
     surname: "Graham",
     email: "[email protected]",
     email_verified_at: "2020-01-03 16:01:53",
     created_at: "2020-01-03 16:01:59",
     updated_at: "2020-01-03 16:01:59",
     deleted_at: null,

>>> \App\Models\User::where('name', 'Buraco')->findOrFail('123b5545-5adc-4c59-9a27-00d035c1d212');
>>> Illuminate/Database/Eloquent/ModelNotFoundException with message 'No query results for model [App/Models/User] 123b5545-5adc-4c59-9a27-00d035c1d212'


>>> \App\Models\User::where('name', 'John')->findOrFail('123b5545-5adc-4c59-9a27-00d035c1d212');
>>> App\Models\User
     id: "123b5545-5adc-4c59-9a27-00d035c1d212",
     name: "John",
     surname: "Graham",
     email: "[email protected]",
     email_verified_at: "2020-01-03 16:01:53",
     created_at: "2020-01-03 16:01:59",
     updated_at: "2020-01-03 16:01:59",
     deleted_at: null,

Outdated:
It took at least two hours to realize that if you chain firstOrFail() method after where() in Laravel 5.6, it basically tries to retrieve the first record of the table and removes where clauses. So call firstOrFail before where.

Model::firstOrFail()->where('something', $value)

Solution 3 - Laravel

## Or Via Scope For Multiple Rows ##

public function scopeGetOrFail ($query)
{
    if (empty($query->count())) {
        abort(404);
    } else {
        return $query->get();
    }
}

Page::whereSlug('about')->getOrFail();
Page::where("slug","about")->getOrFail();

Solution 4 - Laravel

In my opinion maybe you can define function getRouteKeyName() to explicitly taken the column you want when you use static find() for eloquent model.

public function getRouteKeyName(){
  return 'slug';
}

And if you insist, you can write it as static function inside model

public  static function findBySlugOrFail($value){
  //get slug collection or return fail
  return Post::where('slug', '=', $value)->firstOrFail();
}

Solution 5 - Laravel

Try it like this:

Page::where('slug', '=', 'about')->get()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLimon MonteView Question on Stackoverflow
Solution 1 - LaravelAlupothaView Answer on Stackoverflow
Solution 2 - LaravelBuracoView Answer on Stackoverflow
Solution 3 - LaravelCristhofer MontalvoView Answer on Stackoverflow
Solution 4 - Laravelsyafiq zahirView Answer on Stackoverflow
Solution 5 - LaravelrwieruckiView Answer on Stackoverflow