Laravel : Handle findOrFail( ) on Fail

后端 未结 6 1705
灰色年华
灰色年华 2021-02-13 17:31

I am looking for something which can be like findOrDo(). Like do this when data not found. Something could be like

Model::findOrDo($id,function(){
   return \"Da         


        
相关标签:
6条回答
  • 2021-02-13 18:11

    Another option is to modify the default Laravel Exception Handler, found in app/Exceptions/Handler.php on the render() function I made this change:

    public function render($request, Exception $e)
    {
        if(get_class($e) == "Illuminate\Database\Eloquent\ModelNotFoundException") {
            return (new Response('Model not found', 400));
        }
        return parent::render($request, $e);
    }
    

    That way instead of getting a 500, I send back a 400 with a custom message without having to do a try catch on every single findOrFail()

    0 讨论(0)
  • 2021-02-13 18:12
    use Illuminate\Database\Eloquent\ModelNotFoundException;
    
    // Will return a ModelNotFoundException if no user with that id
    try
    {
        $user = User::findOrFail($id);
    }
    // catch(Exception $e) catch any exception
    catch(ModelNotFoundException $e)
    {
        dd(get_class_methods($e)); // lists all available methods for exception object
        dd($e);
    }
    
    0 讨论(0)
  • 2021-02-13 18:13

    An alternative process could be to evaluate a collection instead. So,

    $modelCollection = Model::where('id', $id)->get();
    if(!$modelCollection->isEmpty()) {
        doActions();
    }
    

    I agree it isn't as elegant, a one-liner or as case specific as you or I might like, but aside from writing a try catch statement every time, it's a nice alternative.

    0 讨论(0)
  • 2021-02-13 18:22

    By default, when you use an Eloquent model’s findOrFail in a Laravel 5 application and it fails, it returns the following error:

    ModelNotFoundException in Builder.php line 129:
    'No query results for model [App\Model]'.
    

    So to catch the exception and display a custom 404 page with your error message like "Ooops"....

    Open up the app/Exceptions/Handler.php file, and add the code shown below to the top of the render function:

    public function render($request, Exception $e)
    {
       if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) 
       {
          abort(404, 'Oops...Not found!');
       }
    
       return parent::render($request, $e);
    }
    

    Source: https://selftaughtcoders.com/from-idea-to-launch/lesson-16/laravel-5-findorfail-modelnotfoundexception-show-404-error-page/

    0 讨论(0)
  • 2021-02-13 18:24

    A little later for the party, from laravel 5.4 onward, Eloquent Builder supports macros. So, I would write a macro (in a separate provider) like follows.

    Builder::macro('firstOrElse', function($callback) {
       $res = $this->get();
    
       if($res->isEmpty()) {
           $callback->call($this);
       }
    
       return $res->first();
    });
    

    I can then do a retrieval as follows.

    $firstMatchingStudent = DB::table('students')->where('name', $name)
        ->firstOrElse(function() use ($name) {
            throw new ModelNotFoundException("No student was found by the name $name");
        });
    

    This will assign the first object of the result set if it is not empty, otherwise will adapt the behaviour I pass into the macro as a closure (throw Illuminate\Database\Eloquent\ModelNotFoundException in this case).

    For the case of a model also this would work, except that models always return the builder instance.

    0 讨论(0)
  • 2021-02-13 18:35

    as of Laravel v5.7, you can do this (the retrieving single model variation of @thewizardguy answer)

    // $model will be null if not found
    $model = Model::where('id', $id)->first();
    
    if($model) {
        doActions();
    }
    
    0 讨论(0)
提交回复
热议问题