O encadeamento do Laravel Eloquent Query Builder afeta a consulta base original [duplicado]
Como posso fazer essa consulta funcionar?
$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.
Como posso, então, ter uma coleção básica como ponto inicial que não será modificada por operações get () subsequentes.
Obrigada!
Respostas
Se você tem um construtor e deseja uma nova cópia dele para continuar a construir uma consulta, você pode "clonar" o construtor:
$cloned = clone $query;
Agora $cloned
é seu próprio objeto e você pode construir a consulta como quiser, sem afetar $query
o construtor original.
Se você realmente deseja um clone
método no construtor e ele não existe, você pode macro:
Illuminate\Database\Query\Builder::macro('clone', function () {
return clone $this;
});
Você pode incluir isso no boot
método de um provedor de serviços .
Há um método clone disponível no construtor (Illuminate \ Database \ Query \ Builder) que pode ser usado
$basic_query = Invoices::between_days(15, 7); $paid_invoices = $basic_query->clone()->paid()->get(); $outstanding_invoices = $basic_query->clone()->paid(false)->get();
Atualizar
Para versões do Laravel abaixo de 8.xa, a macro pode ser definida em AppServiceProvider ou em um novo MacroServiceProvider - método de inicialização.
Com MacroServiceProvider - não se esqueça de adicioná-lo à matriz de provedores em 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()
{
//
}
}