2017-12-27 29 views
2

저는 Laracasts : Laravel 5.4를 Scratch 시리즈에서보고 있는데, 쿼리 범위 개념을 접했습니다.Laravel에서 쿼리 범위는 어떻게 작동합니까?

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class Task extends Model 
{ 

    public function scopeIncomplete($query) 
    { 

     return $query->where('completed', 0); 

    } 
} 

내 첫 번째 질문 :

왜 같은 방법 :public function scopeIncomplete($query)이 같은라는 다음 :: 연산자 App\Task::incomplete() 비디오에서

, 우리는이 같은 클래스를 설정?

정적이 아닌 메서드를 정적으로 호출하지 않습니까?

내 두 번째 질문 : $query에서 온 않습니다

? 나는이 이해할 수있는 일부터

는 "기존의"쿼리이지만 다음과 같이 호출됩니다

App\Task::incomplete()->where('id', '>', 1)->get(); 그래서 나는이 변수가 어디에서 오는 정말 모르겠어요.

어쩌면 나중에 더 깊이 설명 하겠지만이 방법에 대해 머리를 감쌀 수는 없습니다.

답변

3

Eloquent에서 두 가지 큰 주제를 다루고 있기 때문에 꽤 광범위합니다.


첫 번째는 Eloquent의 정적 패턴을 정적 패턴으로 전달하기 위해 외관 패턴을 사용하는 것을 말합니다.

facade 패턴은 IoC 컨테이너를 사용하여 클래스의 바운드 또는 새 인스턴스에 메서드 호출을 전달합니다.

외관 패턴은 오버로드와 마술 방법 __callStatic을 사용합니다.


두 번째 질문은 등록 방법 (특히를 분명히 \ 데이터베이스 \ \ 웅변 \ 빌더) 쿼리 빌더 객체에 호출을 전달 웅변의 오버로드를 말합니다. 이것은 Eloquent 모델 자체에서 where() 및 기타 다양한 쿼리 작성기 메서드를 호출 할 수있게합니다. 모델 클래스 내부, 당신은 볼 수 있습니다 : 모델에 정의되지 않은 경우() 또는 불완전() 이후

/** 
* Handle dynamic method calls into the model. 
* 
* @param string $method 
* @param array $parameters 
* @return mixed 
*/ 
public function __call($method, $parameters) 
{ 
    if (in_array($method, ['increment', 'decrement'])) { 
     return $this->$method(...$parameters); 
    } 

    return $this->newQuery()->$method(...$parameters); 
} 

, 그들은 모델 :: newQuery에 의해 반환 된 빌더 클래스에 전달 될 것입니다() . 빌더 __call 방법 내부

, 당신은이 :

if (method_exists($this->model, $scope = 'scope'.ucfirst($method))) { 
     return $this->callScope([$this->model, $scope], $parameters); 
    } 

그래서이 모델 내에서 정의 된 범위를 확인하고이 빌더 인스턴스를 포함 $ 매개 변수를 전달합니다.그래서 요약

, 모델에 대한 전화 : (불완전) 갈 것입니다 :

모델 __call() -> 빌더 __call를() -> 모델 scopeIncomplete (빌더 $ 빌더) 저를 가리키는위한

+1

감사합니다 이 주제에 올바른 방향으로 그들은 꽤 큰 것처럼 보입니다. 나는 할 일이 많습니다. 아마 시리즈를 계속해야 할거야! –

+1

@TimothyFisher Jeffrey는 이처럼 깊은 다이빙을 만질 수 없습니다. 그러나 수업 내용을 직접 살펴보면 토끼 구멍이 어디에 있는지 알 수 있습니다. Eloquent는 유효한 비평 중 하나 인 오버로드를 많이 사용하지만 오버로드를 사용하면 구문을 매우 표현력 있고 사용하기 쉽습니다. Eloquent가 작업을 수행하는 방법에 대해 이해하는 한 모든 세부 사항을 반드시 이해할 필요는 없습니다. – Devon