Is there a static custom find method in the Laravel model?

Should the following Laravel 5 model have a static method findByIdAndCourseOrFail ?

 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 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 do not act on an instance of the section [See note]. On the other hand, in a controller with automatic dependency loading through the Laravel service container, we will act on the instance: $sections = $this->sections-> findByIdAndCourseOrFail(7,3); and my IDE (PhpStorm) goes through if Static .

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

+5
source share
3 answers

I am not sure that local areas should be used this way. But this 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 in both directions:

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

Or

 $model = new Section(); $section = $model->findByIdAndCourseOrFail($id, $courseId); 
+1
source
 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); } } 
+1
source

Personally, I would do this with a static method, I'm not sure if there is a โ€œrightโ€ answer, although how can I do it. The way I separate them from the thought that if I do something with an instance of the model, I do this as a normal public function. If I do something in the compilation, I use statics. For instance:

 $person = new Person(); $person->setAdmin(true); $person->save(); // OR $admins = Person::getAdmins(); 

In the first example, we have a specific instance of Person , and we manipulate it, all the code will simply manipulate this particular instance. In the second example, we act on the entire set of Person , and we want to get a collection of returned objects.

In your case, you will need to initiate a Section instance in order to be able to use your non-static public method, for example:

 $section = new Section(); $foundSection = $section->findByIdAndCourseOrFail(7,3); 

So, $section becomes a temporary variable that is never used. On the other hand, if you made it static, you could call it without having to do it.

 $section = Section::findByIdAndCourseOrFail(7,3); 

Hope this makes sense.

+1
source

Source: https://habr.com/ru/post/1259352/


All Articles