101

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');
Limon Monte
  • 52,539
  • 45
  • 182
  • 213

5 Answers5

235

Try it like this:

Page::where('slug', '=', 'about')->firstOrFail();    
// or without the explicit '='
Page::where('slug', 'about')->firstOrFail();
Mister Verleg
  • 4,053
  • 5
  • 43
  • 68
Alupotha
  • 9,710
  • 4
  • 47
  • 48
6

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: "john.graham@test.com",
     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: "john.graham@test.com",
     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)
Buraco
  • 413
  • 5
  • 9
  • 3
    hmm, I think you must have some other problem. the where clause going first works fine for me in laravel v5.6.23 – Jeff Puckett Oct 03 '18 at 01:49
  • 1
    Yep! It work's but the difference is, in this example querying database then using `where` helper of collections. I meant querying database with `where` clause before it turns into collections. – Buraco Jan 28 '21 at 13:59
6
## 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();
3

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();
}
1

Try it like this:

Page::where('slug', '=', 'about')->get()
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
rwierucki
  • 37
  • 3
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 08 '21 at 12:43