2016-11-06 2 views
5

다음 Larvel 5 모델에서 findByIdAndCourseOrFail 메서드는 정적이어야합니까? 컨트롤러와Laravel 모델의 사용자 정의 찾기 메소드가 정적이어야합니까?

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

    } 


    } 

:

한편으로
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 
} 

, 우리는 제 인스턴스에 작용하지 않는 [참고보기]. 한편, 자동 의존성 주입 컨트롤러가 Laravel's service container 인 경우, $sections = $this->sections-> findByIdAndCourseOrFail(7,3); 인스턴스와 Static 인 경우 IDE (PhpStorm)가 작동합니다.

[참고] :이 의견은 Laravel Models의 작동 방식에 대한 오해 일 수 있습니다. 나에게 나는 find(), findOrFail()을 Class 메소드로, 따라서 find 메소드가 리턴 할 인스턴스가 아닌 Static으로 기대한다.

+0

글쎄,'$ this'는 사용할 수 없습니다 정적 메소드. – Xorifelse

+0

물론, 메소드가 정적으로 변경 되었다면,'$ this->'는'self ::' – Gazzer

+0

으로 변경 될 것입니다. 그러나'where()'와'first()'는 변경이 필요할 것입니다. 그 메소드가 정의되어 있다면'Model' 전체가됩니다. – Xorifelse

답변

1

이 그런 용도로 사용되는지 확실하지 않습니다. 당신이 그것을 두 가지 방법으로 사용할 수있는 컨트롤러에서

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

: :하지만 laravel 5.2에 나를 위해 작동

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

또는

$model = new Section(); 
$section = $model->findByIdAndCourseOrFail($id, $courseId); 
+0

이것은 실제로 올바른 접근법입니다. 소스 코드를 자세히 살펴보면 모델 방법 중 실제로 정적 인 것은 없습니다. model :: find()는 통사론적인 설탕이므로 동일한 특성을 유지하는 스코프를 사용하는 것이 올바른 접근법입니다. – Gazzer

1
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

질문은 메서드를 정적으로 만드는 방법이 아니라 오히려 정적이거나 그렇지 않다. – Gazzer

+0

이 경우에는 ... 정적이어야하며, 나에게 더 합리적이다.이 메소드를 정적으로 호출하여 모델을 반환한다. – Sherif

+0

모델을 이미 가지고 있거나 인스턴스를 찾으면이 모델을 찾을 수 없습니다. – Sherif

1

개인적으로 저는이 방법을 정적 방법으로 만들 것입니다. 그러나 "올바른"대답이 있는지 여부는 확실하지 않습니다. 제가 제 마음 속에서 그들을 구분하는 방법은 제가 모델의 인스턴스에 대해 뭔가를하고 있다면 그것을 일반적인 공공 기능으로 만드는 것입니다. 내가 콜렉션에 뭔가를하고 있다면 정적을 사용합니다. 예를 들어 첫 번째 예에서

$person = new Person(); 
$person->setAdmin(true); 
$person->save(); 

// OR 

$admins = Person::getAdmins(); 

우리가 Person의 특정 인스턴스를 가지고 있고 우리는 그것을 조작하는 모든 코드는 단순히 특정 인스턴스를 조작하는 것입니다. 두 번째 예제에서 우리는 Person의 전체 컬렉션에 대해 작업하고 있으며 컬렉션의 객체가 반환되기를 원합니다. 귀하의 경우에는

Section의 인스턴스를 시작해야하는 것과 같이, 당신의 비 정적 공공 방법을 사용 할 수 있도록 :

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

그래서 $section 정말 사용되지 않습니다 임시 변수가된다 . 다른 한편으로는 정적이라면 이것을하지 않고도 호출 할 수 있습니다.

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

희망이 있습니다.

+0

답장을 보내 주셔서 감사합니다. 관련 : "이 경우와 같이 비 정적 공용 메서드를 사용할 수 있으려면 섹션의 인스턴스를 시작해야합니다." 사실, 그렇지 않습니다. 컨트롤러에서 리플렉션을 사용하고 인스턴스가 생성자에 자동으로 주입됩니다. 'public function __construct (Section $ sections) {$ this-> sections sections = $ sections}'이고,이 경우 static은 일반적으로 덜 논리적입니다. – Gazzer

+1

어쨌든 나는이 경우에 대해서 예외를 만들 것이라고 생각하지 않는다. 다른 시간에 다른 곳에서 해당 기능을 사용해야하는 경우에는 어떻게해야합니까? 나는 네 표준에 충실하겠다. – Pitchinnate

+0

나는 이것이 예외를 만들고 있다고 생각하지 않는다. 서비스 컨테이너를 이용한 자동 주입은 광범위하게 사용되며'find()'메소드 자체는 정적으로 호출되지 않으며 인스턴스를 사용하여 find() 호출을 수행 할 때 정적 주입으로 인해 주입의 이점을 무효화합니다. 내'findByCustom()'호출이 이상하게 보일 것입니다! – Gazzer

관련 문제