>백엔드 개발 >PHP 튜토리얼 >Laravel의 쿼리 스코프를 마스터하는 법을 배우십시오

Laravel의 쿼리 스코프를 마스터하는 법을 배우십시오

Emily Anne Brown
Emily Anne Brown원래의
2025-03-06 02:28:09506검색
<p> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174119929536701.jpg" class="lazy" alt="Learn to master Query Scopes in Laravel"> <lar> 라벨 애플리케이션을 구축 할 때는 응용 프로그램 전체의 여러 장소에서 사용되는 제약 조건으로 쿼리를 작성해야 할 수도 있습니다. 어쩌면 멀티 테넌트 응용 프로그램을 구축하고 있으며 사용자 팀이 필터링하기 위해 쿼리에 </lar></p> 제약 조건을 지속적으로 추가해야합니다. 또는 블로그를 작성하고 있으며 블로그 게시물이 게시 된 경우 필터를 필터링하기 위해 쿼리에 <p> 제약 조건을 지속적으로 추가해야합니다. <code>where</code> Laravel에서는 쿼리 스코프를 사용하여 이러한 제약을 한 곳에 깔끔하게 유지하고 재사용 할 수 있습니다. <code>where</code> 이 기사에서는 로컬 쿼리 범위와 글로벌 쿼리 범위를 연구 할 것입니다. 우리는 둘 사이의 차이, 자신의 쿼리 범위를 만드는 방법 및 테스트를 작성하는 방법을 배우게됩니다. </p> <article>이 기사를 읽은 후에는 Laravel 응용 프로그램에서 쿼리 스코프를 자신있게 사용할 수 있어야합니다. <p> <ery> 쿼리 스코프 란 무엇입니까? </ery></p> <p> <ope> 쿼리 범위를 사용하면 재사용 가능한 방식으로 웅변 쿼리의 제약 조건을 정의 할 수 있습니다. 이들은 일반적으로 Laravel 모델의 메소드 또는 </ope></p> 인터페이스를 구현하는 클래스로 정의됩니다. <p> <they> 재사용 가능한 논리를 한 곳에서 정의하는 데 이상적 일뿐 만 아니라 간단한 기능 호출 후 복잡한 쿼리 제약 조건을 숨겨 코드를 더 읽기 쉽게 만들 수 있습니다. </they></p> <ang> 쿼리 범위는 두 가지 유형으로 나뉩니다 <h1> <r> 로컬 쿼리 범위 - 이러한 범위를 수동으로 쿼리에 적용해야합니다. </r> </h1> <sc> 글로벌 쿼리 스코프 - 기본적으로 이러한 범위는 쿼리가 등록 된 경우 모델의 모든 쿼리에 적용됩니다. <hr> <p> <ever> Laravel에 내장 된 "Soft Delete"기능을 사용한 경우 쿼리 범위를 무의식적으로 사용했을 수 있습니다. Laravel은 로컬 쿼리 범위를 사용하여 모델에서 <code>IlluminateDatabaseEloquentScope</code> 및 </ever></p>와 같은 메소드를 제공합니다. 또한 글로벌 쿼리 범위를 사용하여 모델의 모든 쿼리에 <p> 제약 조건을 자동으로 추가하여 쿼리에서 기본적으로 소프트 삭제 레코드를 반환하지 않도록합니다. </p> <how> Laravel 애플리케이션에서 로컬 쿼리 스코프 및 글로벌 쿼리 스코프를 생성하고 사용하는 방법을 살펴 보겠습니다. <p> 로컬 쿼리 스코프 </p> 로컬 쿼리 범위는 웅변 모델의 메소드로 정의되어 모델 쿼리에 수동으로 적용 할 수있는 제약 조건을 정의 할 수 있습니다. <ul> <are> 관리자 패널이있는 블로그 응용 프로그램을 작성한다고 가정 해 봅시다. 관리자 패널에는 게시 된 블로그 게시물을 나열하고 게시되지 않은 블로그 게시물을 나열하는 두 페이지가 있습니다. <li><that> 우리는 블로그 게시물이 모델을 사용하여 액세스하고 데이터베이스 테이블에 블로그 게시물의 게시 시간을 저장하기위한 빈 <p> 열이 있다고 가정합니다. 과거에 <code>AppModelsArticle</code>가 나열되면 블로그 게시물이 게시 된 것으로 간주됩니다. 미래에 가 나열되거나 <code>published_at</code> 인 경우 블로그 게시물은 게시되지 않은 것으로 간주됩니다. <code>published_at</code> <ished> 게시 된 블로그 게시물을 얻으려면 다음 쿼리를 쓸 수 있습니다. <code>published_at</code> 미공개 블로그 게시물을 얻으려면 다음 쿼리를 작성할 수 있습니다. <code>null</code> <ery> 위의 쿼리는 특별히 복잡하지 않습니다. 그러나 응용 프로그램 전체의 여러 장소에서 사용한다고 가정 해 봅시다. 발생 횟수가 증가함에 따라 실수를 저지르거나 한 곳에서 쿼리 업데이트를 잊어 버릴 가능성이 증가하고 있습니다. 예를 들어, 개발자는 실수로 </ery></ished></p> 대신 <p>를 사용하여 게시 된 블로그 게시물을 쿼리 할 수 ​​있습니다. 또는 블로그 게시물이 게시되었는지 확인하는 논리가 변경 될 수 있으며 모든 쿼리를 업데이트해야합니다. </p> <qu> 이것은 쿼리 스코프가 매우 유용한 곳입니다. 따라서 <pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->where('published_at', '<', now()) ->get();</code></pre> 모델에서 로컬 쿼리 범위를 만들어 쿼리를 구성합시다. <p> <sc> 로컬 쿼리 스코프는 </sc></p>로 시작하는 메소드를 만들고 스코프의 예상 이름으로 끝나는 메소드를 작성하여 정의됩니다. 예를 들어, <pre class="brush:php;toolbar:false"><code>use App\Models\Article; use Illuminate\Contracts\Database\Eloquent\Builder; $unpublishedPosts = Article::query() ->where(function (Builder $query): void { $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }) ->get();</code></pre>라는 메소드는 모델에서 <p> 범위를 생성합니다. 이 메소드는 <accept accept> 인스턴스를 수락하고 인스턴스를 반환해야합니다. <code>>=</code> <r> 우리는 두 범위를 <code><</code> 모델에 추가합니다 : <🎜 🎜> </p> <in> 위의 예에서 보았 듯이, <p> 제약 조건을 이전 쿼리에서 두 가지 별도의 방법으로 옮겼습니다. 이제 이러한 범위를 다음과 같이 쿼리에 사용할 수 있습니다. <code>AppModelsArticle</code> <opinion> 개인적인 견해로는 이러한 쿼리를 읽고 이해하기가 더 쉽다는 것을 알게됩니다. 이것은 또한 향후 동일한 제약 조건으로 쿼리를 작성해야한다면 이러한 범위를 재사용 할 수 있음을 의미합니다. </p> <sc> 글로벌 쿼리 스코프 <p> <code>scope</code> <sc> 글로벌 쿼리 스코프는 로컬 쿼리 범위와 유사한 함수를 수행합니다. 그러나 쿼리별로 수동으로 적용되지 않지만 모델의 모든 쿼리에 자동으로 적용됩니다. <code>scopePublished</code> <earlier> 앞에서 언급했듯이 Laravel의 내장 "Soft Delete"기능은 <code>published</code> Global Query 범위를 사용합니다. 이 범위는 모델의 모든 쿼리에 자동으로 <code>IlluminateContractsDatabaseEloquentBuilder</code> 제약 조건을 추가합니다. 작동 방식을 이해하는 데 관심이 있으시면 GitHub의 소스 코드를 확인하십시오. <code>IlluminateContractsDatabaseEloquentBuilder</code> 예를 들어 <sup> 관리자 패널이있는 다중 테넌트 블로그 응용 프로그램을 작성한다고 가정 해 봅시다. 사용자가 팀에 속한 기사를 볼 수 있도록 허용 할 수도 있습니다. 따라서 다음과 같은 쿼리를 쓸 수 있습니다<pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->where('published_at', '<', now()) ->get();</code> 이 쿼리는 좋지만 <p> 제약 조건을 추가하는 것을 잊기 쉽습니다. 다른 쿼리를 작성하고 제약 조건을 추가하는 것을 잊어 버린 경우 응용 프로그램에 오류가 발생하여 사용자가 팀의 일부가 아닌 기사와 상호 작용할 수 있습니다. 물론, 우리는 이런 일이 일어나기를 원하지 않습니다! <code>where</code> 이를 방지하기 위해 모든 모델 쿼리에 자동으로 적용 할 수있는 전역 범위를 만들 수 있습니다. </p> <create>#전역 쿼리 범위를 만드는 방법 <a> 열로 모든 쿼리를 필터링하는 전역 쿼리 범위를 만들어 봅시다. <code>AppModelArticle</code> <for>이 기사의 목적 상, 예제를 간단하게 유지합니다. 실제 응용 프로그램에서는 사용자가 인증되지 않았거나 사용자가 여러 팀에 속하는 것과 같은 상황을 다루기 위해보다 강력한 접근 방식을 사용할 수 있습니다. 그러나 현재로서는 간단하게 유지하여 글로벌 쿼리 범위의 개념에 집중할 수 있습니다. </for></a></create></r></accept></p> <run> 우리는 먼저 터미널에서 다음 장인 명령을 실행할 것입니다 : <h3> </h3> <created> 이것은 새로운 파일을 만들어야합니다. 이 파일을 업데이트 한 다음 완성 된 코드를 살펴 봅니다. <p> <code> 위의 코드 예제에서 인터페이스를 구현하고 라는 단일 메소드가있는 새로운 클래스가 있음을 알 수 있습니다. 이것이 모델 쿼리에 적용 할 제약 조건을 정의하는 방법입니다. <code>team_id</code> <ope> 우리의 글로벌 범위를 사용할 수 있습니다. 쿼리를 사용자 팀에 좁히려는 모든 모델에 이것을 추가 할 수 있습니다. </ope></code></p> <it> <p> 모델에 적용합시다. </p> <global>#Apply Global Query Scope <ways> 글로벌 범위를 모델에 적용하는 몇 가지 방법이 있습니다. 첫 번째 방법은 모델에서 <p> 속성을 ​​사용하는 것입니다. </p> <to to> 다른 방법은 <code>use App\Models\Article; use Illuminate\Contracts\Database\Eloquent\Builder; $unpublishedPosts = Article::query() ->where(function (Builder $query): void { $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }) ->get();</code> 메소드에서 <p> 메소드를 사용하는 것입니다. <code>app/Models/Scopes/TeamScope.php</code> <the> 두 방법 모두 </the></p> 모델의 모든 쿼리에 <pre class="brush:php;toolbar:false"><code>declare(strict_types=1); namespace App\Models; use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; final class Article extends Model { public function scopePublished(Builder $query): Builder { return $query->where('published_at', '<', now()); } public function scopeNotPublished(Builder $query): Builder { return $query->where(function (Builder $query): Builder { return $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }); } // ... }</code></pre> 제약 조건을 적용합니다. <p> <can> 이것은 이제 <code>IlluminateDatabaseEloquentScope</code> 열로 필터링에 대해 걱정하지 않고 쿼리를 쓸 수 있음을 의미합니다. <code>apply</code> <ume> 사용자가 </ume></can></p> 인 인 팀에 속한다고 가정하면 위의 쿼리에 대해 다음 SQL이 생성됩니다. <p> 이것은 멋지다, 맞습니까? ! </p> <ous> #Anonymous Global Query Scope <p> <def> 글로벌 쿼리 범위를 정의하고 적용하는 또 다른 방법은 익명의 글로벌 범위를 사용하는 것입니다. <code>AppModelsArticle</code> <our> 익명의 글로벌 범위를 사용하기 위해 모델을 업데이트합시다 : </our></def></p> <code> 위 코드 예제에서 <h3> 메소드를 사용하여 모델의 </h3> 메소드에서 익명의 글로벌 범위를 정의했습니다. <ts> 메소드는 두 개의 매개 변수를 수락합니다 : <ul> <the the> 범위의 이름 - 쿼리에서 무시 해야하는 경우이 이름을 사용하여 범위 <li>를 참조 할 수 있습니다. <ain> 스코프 제약 조건 - 제약 조건에 적용 할 폐쇄를 정의합니다 </ain> </li> <methods> 다른 방법과 마찬가지로, 이것은 모델의 모든 쿼리에 <li> 제약 조건을 적용합니다. </li> 내 경험상 익명의 글로벌 범위는 별도의 클래스에서 글로벌 범위를 정의하는 것만 큼 일반적이지 않습니다. 그러나 비상 사태의 경우 이용 가능하다는 것을 아는 것이 좋습니다. </methods></the> </ul> <global>#inignore Global Query Scope <want> 때로는 모델에 적용된 글로벌 쿼리 범위를 사용하지 않는 쿼리를 작성할 수도 있습니다. 예를 들어, 글로벌 쿼리 범위에 관계없이 모든 레코드를 포함 해야하는 보고서 또는 분석 쿼리를 구축 할 수 있습니다. <p> <the>이 경우 두 가지 방법 중 하나를 사용하여 전역 범위를 무시할 수 있습니다. <code>where('team_id', Auth::user()->team_id)</code> <is> 첫 번째 방법은 <code>AppModelsArticle</code>입니다. 이 방법은 매개 변수가 전달되지 않으면 모델의 모든 글로벌 스코프를 무시할 수 있습니다. </is></the></p> <you> 또는 주어진 글로벌 스코프 세트 만 무시하려면 범위 이름을 <p> 메소드로 전달할 수 있습니다 : . </p> <above> 위의 예에서, 우리는 라는 또 다른 가상의 익명의 글로벌 범위를 무시합니다. <you> 또는 단일 글로벌 범위 만 무시하려면 <p> 메소드를 사용할 수 있습니다. </p> 글로벌 쿼리 범위 글로벌 쿼리 범위는 모델을 통해 만들어진 쿼리에만 적용된다는 것을 기억하는 것이 중요합니다. 모양을 사용하여 데이터베이스 쿼리를 작성하면 글로벌 쿼리 범위가 적용되지 않습니다. <p> 예를 들어 <sup>,이 쿼리를 작성하고 로그인 한 사용자 팀의 기사 만 크롤링하기를 원한다고 가정 해 봅시다. </sup></p> <qu> 위의 쿼리에서 <p> 모델에 <code>withoutGlobalScopes</code>의 글로벌 쿼리 범위가 정의 되더라도 범위는 적용되지 않습니다. 따라서 데이터베이스 쿼리에서 제약 조건이 수동으로 적용되도록해야합니다. </p> <ery> 테스트 로컬 쿼리 범위 <pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->where('published_at', '<', now()) ->get();</code></pre> <have> 이제 쿼리 스코프를 만들고 사용하는 방법을 배웠으므로 테스트를 작성하는 방법을 살펴 보겠습니다. <p> <ways> 쿼리의 범위를 테스트하는 방법에는 여러 가지가 있으며 선택한 방법은 개인 선호도 또는 작성하는 범위의 내용에 따라 다를 수 있습니다. 예를 들어, 범위에 대해 더 많은 단위 스타일 테스트를 작성할 수 있습니다. 또는 컨트롤러와 같은 컨텍스트에서 범위를 테스트하는 더 많은 통합 스타일 테스트를 작성할 수도 있습니다. <code>withoutGlobalScopes</code> <i> 개인적으로, 나는 두 가지를 혼합하여 범위가 올바른 제약 조건을 추가하고 스코프가 실제로 쿼리에 사용되고 있는지 확인할 수 있습니다. </i></ways></p> <with> 이전 예제 <pre class="brush:php;toolbar:false"><code>use App\Models\Article; use Illuminate\Contracts\Database\Eloquent\Builder; $unpublishedPosts = Article::query() ->where(function (Builder $query): void { $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }) ->get();</code></pre> 및 <p> 범위부터 시작하여 일부 테스트를 작성하겠습니다. 우리는 두 가지 다른 테스트 (각 범위마다 하나씩)를 작성해야합니다.</p> <ul> 테스트 점검 <li> 범위는 게시 된 기사 만 반환합니다. <code>published</code> 테스트 점검 범위는 게시되지 않은 기사 만 반환합니다. </li> <li> <at>이 테스트를보고 수행중인 작업에 대해 논의합시다 : <code>notPublished</code> </at> </li> <in> 위의 테스트 파일에서 볼 수 있습니다. 먼저 </in> </ul> 메소드로 일부 데이터를 만듭니다. 우리는 두 개의 출판 된 기사, 하나의 예정되지 않은 기사와 하나의 정렬 된 기사를 만들었습니다. <p> <a> 그런 다음 게시 된 기사 만 반환하기 위해 </a></p> 범위를 확인하는 테스트 ()가 있습니다. 미공개 기사 만 반환하도록 범위를 점검하는 테스트 ()도 있습니다. <pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->where('published_at', '<', now()) ->get();</code></pre> 이렇게함으로써 쿼리 범위가 예상대로 제약 조건을 적용하고 있는지 확인할 수 있습니다. <p> <controll> 컨트롤러의 테스트 범위 <code>setUp</code> 우리가 언급했듯이 쿼리의 범위를 테스트하는 또 다른 방법은 컨트롤러에 사용 된 컨텍스트에서 쿼리 범위를 테스트하는 것입니다. 스코프의 격리 테스트는 스코프가 쿼리에 올바른 제약 조건을 추가하고 있다고 주장 할 수 있지만 실제로 스코프가 예상대로 응용 프로그램에서 사용되는지 테스트하지는 않습니다. 예를 들어, 컨트롤러 메소드의 쿼리에 </controll></p> 범위를 추가하는 것을 잊을 수 있습니다. <p> <err> 이러한 유형의 오류는 컨트롤러 방법에서 스코프를 사용할 때 올바른 데이터를 반환하는 테스트를 작성하여 캡처 할 수 있습니다. <code>only_published_articles_are_returned</code> <the> 다중 테넌트 블로그 애플리케이션이있는 예를 들어 기사를 나열하는 컨트롤러 방법에 대한 테스트를 작성하겠습니다. 다음과 같이 매우 간단한 컨트롤러 방법이 있다고 가정 해 봅시다. <code>published</code> <that> 우리는 <code>only_not_published_articles_are_returned</code> 모델이 우리의 를 적용했다고 가정합니다. <code>notPublished</code> <ert> 우리는 사용자 팀에 속한 기사 만 반환한다고 주장합니다. 테스트 케이스는 다음과 같이 보일 수 있습니다 </ert></that></the></err></p> <test> 위의 테스트에서 우리는 두 팀을 만들고 있습니다. 그런 다음 Team One에 속한 사용자를 만듭니다. 우리는 팀 1을위한 3 개의 기사와 팀 2에 대한 기사를 만들었습니다. 그런 다음 사용자 역할을하고 기사를 나열하는 컨트롤러 방법에 요청합니다. 컨트롤러 방법은 Team One에 속하는 기사 3 개만 리턴해야하므로 기사 ID를 비교하여 해당 기사 만 반환한다고 주장합니다. <p> 이는 컨트롤러 방법에서 예상대로 글로벌 쿼리 범위가 사용되고 있음을 의미합니다. </p> <h1> 결론 </h1> 이 기사에서는 로컬 쿼리 범위와 글로벌 쿼리 범위에 대해 배웠습니다. 우리는 그들 사이의 차이점, 만들고 사용하는 방법, 테스트를 작성하는 방법을 배웠습니다. <hr> <now> 이제 Laravel 애플리케이션에서 쿼리 스코프를 자신있게 사용할 수 있기를 바랍니다. <p></p></now></test></with></have></ery></qu></you></above></you></want></global></ts></code></ous></to></ways></global></it></created></run></qu></that></li></are> </ul></how></sc></ang></article>

위 내용은 Laravel의 쿼리 스코프를 마스터하는 법을 배우십시오의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.