Dealing with data not found in Laravel

2019-09-12 16:33发布

问题:

Laravel has a built-in method called findOrfail() described here:

Not Found Exceptions

Sometimes you may wish to throw an exception if a model is not found. This is particularly useful in routes or controllers. The findOrFail and firstOrFail methods will retrieve the first result of the query. However, if no result is found, a Illuminate\Database\Eloquent\ModelNotFoundException will be thrown:

$model = App\Flight::findOrFail(1);

$model = App\Flight::where('legs', '>', 100)->firstOrFail();

But what if you want to write your own code which deals with no result found. So in my controller I want something like:

public function show($id)
{
    $data = JobCardHead::where('JobCardNum', $id)->first();

    If no data found then 
       some code
    else
       some code

回答1:

What does Eloquent return in case no model is found for the methods that do not throw an exception? I'm guessing it's either null or false. So, you could check the return value of the first() call:

$data = JobCardHead::where('JobCardNum', $id)->first();

if ($data) {
  // found it
} else {
  // not found
}

Or, knowing that firstOrFail() throws an exception, you could wrap the call in a try/catch block:

use Illuminate\Database\Eloquent\ModelNotFoundException;

//..

try {
    $data = JobCardHead::where('JobCardNum', $id)->first();
} catch (ModelNotFoundException $e) {
    // Data not found. Here, you should make sure that the absence of $data won't break anything
}

// Here $data is an instance of the model you wanted

The exact approach you should pick actually depends on your usecase a lot.

UPD. By the way, if $id here is your primary key here, you should simply use find($id) or findOrFail($id), as described here



回答2:

Laravel returns null on first() calls to your model when no records are returned.

https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Query/Builder.php#L1548

So for example you could do this as an even cleaner solution:

public function show($id)
{
    if ($job = JobCardHead::where('JobCardNum', $id)->first()) {
        // Record was found!

        return view('job.show', compact('job'));
    }

    return view('404');
}