Limon Monte
Limon Monte

Reputation: 54409

Laravel - find by custom column or fail

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');

Upvotes: 105

Views: 178461

Answers (5)

Alupotha
Alupotha

Reputation: 10103

Try it like this:

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

Upvotes: 244

rwierucki
rwierucki

Reputation: 37

Try it like this:

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

Upvotes: 1

Cristhofer Montalvo
Cristhofer Montalvo

Reputation: 71

## 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();

Upvotes: 7

syafiq zahir
syafiq zahir

Reputation: 31

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

Upvotes: 3

Buraco
Buraco

Reputation: 461

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)

Upvotes: 7

Related Questions