Die Verkettung von Laravel Eloquent Query Builder wirkt sich auf die ursprüngliche Basisabfrage aus [Duplikat]
Wie kann ich diese Abfrage zum Laufen bringen?
$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.
Wie kann ich dann eine Basissammlung als Startpunkt haben, die durch nachfolgende get () - Operationen nicht geändert wird?
Vielen Dank!
Antworten
Wenn Sie einen Builder haben und eine neue Kopie des Builders möchten, damit Sie weiterhin eine Abfrage daraus erstellen können, können Sie den Builder "klonen":
$cloned = clone $query;
Jetzt $cloned
ist es ein eigenes Objekt und Sie können die Abfrage so erstellen, wie Sie möchten, ohne dass dies Auswirkungen auf $query
den ursprünglichen Builder hat.
Wenn Sie wirklich eine clone
Methode für den Builder möchten und diese nicht vorhanden ist, können Sie sie makro:
Illuminate\Database\Query\Builder::macro('clone', function () {
return clone $this;
});
Sie können dies in die boot
Methode eines Dienstanbieters einfügen .
Im Builder steht eine Klonmethode zur Verfügung (Illuminate \ Database \ Query \ Builder), die verwendet werden kann
$basic_query = Invoices::between_days(15, 7); $paid_invoices = $basic_query->clone()->paid()->get(); $outstanding_invoices = $basic_query->clone()->paid(false)->get();
Aktualisieren
Für Laravel-Versionen unter 8.xa kann ein Makro entweder in AppServiceProvider oder in einer neuen MacroServiceProvider- Boot-Methode definiert werden.
Mit MacroServiceProvider - vergessen Sie nicht, es dem Provider-Array in hinzuzufügen 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()
{
//
}
}