Le chaînage de Laravel Eloquent Query Builder affecte la requête de base d'origine [dupliquer]
Comment puis-je faire fonctionner cette requête?
$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.
Comment puis-je alors avoir une collection de base comme point de départ qui ne sera pas modifiée par les opérations get () suivantes.
Merci!
Réponses
Si vous avez un générateur et que vous souhaitez une nouvelle copie du générateur afin de pouvoir continuer à créer une requête à partir de celui-ci, vous pouvez "cloner" le générateur:
$cloned = clone $query;
Maintenant, $cloned
c'est son propre objet et vous pouvez créer la requête comme vous le souhaitez sans avoir d'effet sur $query
le générateur d'origine.
Si vous voulez vraiment une clone
méthode sur le générateur et qu'elle n'existe pas, vous pouvez la macro:
Illuminate\Database\Query\Builder::macro('clone', function () {
return clone $this;
});
Vous pouvez lancer cela dans la boot
méthode d' un fournisseur de services .
Il existe une méthode de clonage disponible sur le générateur (Illuminate \ Database \ Query \ Builder) qui peut être utilisée
$basic_query = Invoices::between_days(15, 7); $paid_invoices = $basic_query->clone()->paid()->get(); $outstanding_invoices = $basic_query->clone()->paid(false)->get();
Mettre à jour
Pour les versions Laravel inférieures à 8.xa, la macro peut être définie dans AppServiceProvider ou dans une nouvelle méthode de démarrage MacroServiceProvider .
Avec MacroServiceProvider - n'oubliez pas de l'ajouter au tableau des fournisseurs dans 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()
{
//
}
}