Laravel Eloquent Query Builder 체이닝은 원래 기본 쿼리에 영향을줍니다.
Dec 15 2020
이 쿼리가 작동하도록하려면 어떻게해야합니까?
$basic_query = Invoices::between_days(15, 7); // This is a collection of invoices from 15 days ago, to seven days in the future. Notice I am not getting this query, it´s still just a builder instance. If you do dd($basic_query->get()) you get 100 invoices, 60 of them paid, 40 of them outstanding.
$paid_invoices = $basic_query->paid()->get(); // This returns the collection of 60 paid invoices without problems. BUT MODIFIES $basic query, if you dd($basic query->get()) at this point, you only get the 60 paid invoices, not the full 100 invoices collection. ¿?!!!
$outstanding_invoices = $basic_query->paid(false)->get(); // This query will always be empty, even though there are many outstanding invoices. If you dd($basic_query->get()) at this point, you get an empty collection. The 100 invoices are lost.
그런 다음 후속 get () 작업에 의해 수정되지 않는 시작점으로 기본 컬렉션을 가질 수 있습니다.
감사합니다!
답변
2 lagbox Dec 15 2020 at 01:31
빌더가 있고 빌더의 새 사본이 필요하여 여기에서 쿼리를 계속 빌드 할 수있는 경우 빌더를 "복제"할 수 있습니다.
$cloned = clone $query;
이제 $cloned
자체 개체이며 $query
원래 작성기 인에 영향을주지 않고 원하는 방식으로 쿼리를 작성할 수 있습니다 .
clone
빌더 에서 메소드가 정말로 필요하고 존재하지 않는 경우 매크로를 사용할 수 있습니다.
Illuminate\Database\Query\Builder::macro('clone', function () {
return clone $this;
});
서비스 공급자의 boot
메서드 에이를 던질 수 있습니다 .
2 Donkarnash Dec 15 2020 at 01:35
빌더 (Illuminate \ Database \ Query \ Builder)에서 사용할 수있는 복제 방법이 있습니다.
$basic_query = Invoices::between_days(15, 7); $paid_invoices = $basic_query->clone()->paid()->get(); $outstanding_invoices = $basic_query->clone()->paid(false)->get();
최신 정보
8.xa 이하의 Laravel 버전의 경우 매크로는 AppServiceProvider 또는 새로운 MacroServiceProvider- 부팅 방법 에서 정의 할 수 있습니다 .
MacroServiceProvider 사용-공급자 배열에 추가하는 것을 잊지 마십시오. config/app.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Query\Builder;
class MacroServiceProvider extends ServiceProvider
{
public function boot()
{
Builder::macro('clone', function() {
return clone $this;
});
}
public function register()
{
//
}
}