Цепочка построителя запросов Laravel Eloquent влияет на исходный базовый запрос [дубликат]
Как я могу заставить этот запрос работать?
$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 ().
Спасибо!
Ответы
Если у вас есть построитель, и вам нужна новая копия построителя, чтобы вы могли продолжить построение запроса из него, вы можете «клонировать» построитель:
$cloned = clone $query;
Теперь $cloned
это отдельный объект, и вы можете построить запрос, как хотите, не влияя на $query
исходный конструктор.
Если вам действительно нужен clone
метод в построителе, а он не существует, вы можете его макрос:
Illuminate\Database\Query\Builder::macro('clone', function () {
return clone $this;
});
Вы можете использовать это в boot
методе поставщика услуг .
В построителе доступен метод клонирования (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();
Обновлять
Для версий Laravel ниже 8.xa макрос может быть определен либо в 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()
{
//
}
}