Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should a custom find method on a Laravel Model be static?

In the following Laravel 5 Model should the findByIdAndCourseOrFail method be static?

class Section extends Model {

    //should this method be static?
    public function findByIdAndCourseOrFail($id, $courseId)
    {

        $result = $this->where('id', $id)->where('course_id', $courseId)->first();

        if (!is_null($result))
        {
            return $result;
        }

        throw (new ModelNotFoundException())->setModel(Section::class);

    }


    }

With the controller:

class SectionsController extends Controller {

protected $sections;

public function __construct(Section $section)
{

    $this->sections = $section;

}

public function foo($id, $courseId)  //illustration only
{
     $section = $this->sections->findOrFail($id);   

     $section = $this->sections->findByIdAndCourseOrFail($id, $courseId);  
     //would need to be non-static

     $section = Section::findByIdAndCourseOrFail($id, $courseId); 
     //weird when compared with find above
}

On the one hand, we're not acting on a Section instance [See Note]. On the other hand, in a controller with auto-dependency injection through Laravel's service container we'd act on an instance: $sections = $this->sections-> findByIdAndCourseOrFail(7,3); and my IDE (PhpStorm) squawks if Static.

[Note]: This comment may be a misunderstanding of how Laravel Models work. For me, I would expect that find(), findOrFail() to be Class methods and thus Static as opposed to the instance that a find method would return.

like image 274
Gazzer Avatar asked Oct 17 '22 23:10

Gazzer


2 Answers

I'm not sure if local scopes are meant to be used like that. But it works for me on laravel 5.2:

public function scopeFindByIdAndCourseOrFail($query, $id, $courseId)
{
    $result = $query->where('id', $id)->where('course_id', $courseId)->first();

    if (!is_null($result))
    {
        return $result;
    }

    throw (new ModelNotFoundException())->setModel(Section::class);
}

In the controller you can use it both ways:

$section = Section::findByIdAndCourseOrFail($id, $courseId);

Or

$model = new Section();
$section = $model->findByIdAndCourseOrFail($id, $courseId);
like image 111
Paul Spiegel Avatar answered Oct 21 '22 03:10

Paul Spiegel


class Section extends Model {


public static function findByIdAndCourseOrFail($id, $courseId)
{

    $result = self::where('id', $id)->where('course_id', $courseId)->first();

    if (!is_null($result))
    {
        return $result;
    }

    throw (new ModelNotFoundException())->setModel(Section::class);

}


}
like image 27
Sherif Avatar answered Oct 21 '22 04:10

Sherif