Tworzenie łańcuchów Laravel Eloquent Query Builder wpływa na oryginalne zapytanie podstawowe [duplikat]
Jak mogę sprawić, by to zapytanie zadziałało?
$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.
Jak więc mogę mieć podstawową kolekcję jako punkt początkowy, który nie będzie modyfikowany przez kolejne operacje get ().
Dziękuję Ci!
Odpowiedzi
Jeśli masz konstruktora i chcesz mieć nową kopię tego kreatora, aby móc kontynuować tworzenie zapytania, możesz go „sklonować”:
$cloned = clone $query;
Teraz $cloned
jest własnym obiektem i możesz zbudować zapytanie tak, jak chcesz, bez wpływu na $query
oryginalnego konstruktora.
Jeśli naprawdę chcesz mieć clone
metodę w konstruktorze, a ona nie istnieje, możesz ją makro:
Illuminate\Database\Query\Builder::macro('clone', function () {
return clone $this;
});
Możesz to wrzucić do boot
metody dostawcy usług .
W konstruktorze dostępna jest metoda klonowania (Illuminate \ Database \ Query \ Builder), której można użyć
$basic_query = Invoices::between_days(15, 7); $paid_invoices = $basic_query->clone()->paid()->get(); $outstanding_invoices = $basic_query->clone()->paid(false)->get();
Aktualizacja
Dla wersji Laravel poniżej 8.x makro można zdefiniować w AppServiceProvider lub w nowej metodzie MacroServiceProvider - boot.
Z MacroServiceProvider - nie zapomnij dodać go do tablicy dostawców w 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()
{
//
}
}