Метод clone
Метод clone применяется к экземпляру построителя запросов Eloquent
или Query Builder и возвращает его полную копию.
Клонирование запроса может быть полезно, когда необходимо
сохранить состояние запроса в определённый момент,
чтобы затем модифицировать его без изменения оригинала.
Метод не принимает никаких параметров и возвращает
новый экземпляр того же класса запроса.
Синтаксис
<?php
$clone = $query->clone();
?>
Пример
Давайте создадим базовый запрос для выборки статей, затем клонируем его для получения дополнительной фильтрации:
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Http\Request;
class ArticleController extends Controller
{
public function index()
{
$baseQuery = Article::where('status', 'published');
$cloneQuery = $baseQuery->clone();
$allPublished = $baseQuery->get();
$recentPublished = $cloneQuery->where('created_at', '>', now()->subDays(7))->get();
return view('articles.index', [
'allPublished' => $allPublished,
'recentPublished' => $recentPublished
]);
}
}
?>
Результат выполнения кода для $allPublished:
["article 1", "article 2", "article 3", "article 4", "article 5"]
Результат выполнения кода для $recentPublished:
["article 4", "article 5"]
Пример
Давайте воспользуемся методом clone для построения
нескольких вариантов запроса на основе одного базового:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
$baseQuery = User::where('active', true);
$admins = $baseQuery->clone()->where('role', 'admin')->get();
$editors = $baseQuery->clone()->where('role', 'editor')->get();
$viewers = $baseQuery->clone()->where('role', 'viewer')->get();
return response()->json([
'admins' => $admins,
'editors' => $editors,
'viewers' => $viewers
]);
}
}
?>
Результат выполнения кода:
{
"admins": ["admin 1", "admin 2"],
"editors": ["editor 1", "editor 2", "editor 3"],
"viewers": ["viewer 1"]
}
Пример
Покажем, что клонирование запроса позволяет сохранить применённые условия сортировки и ограничения:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
$query = Post::where('published', true)
->orderBy('created_at', 'desc')
->limit(10);
$firstPage = $query->clone()->get();
$secondPage = $query->clone()->offset(10)->get();
$res = [
'firstPage' => $firstPage,
'secondPage' => $secondPage
];
return $res;
}
}
?>
Результат выполнения кода:
[
"firstPage" => ["post 1", "post 2", "post 3", "post 4", "post 5", "post 6", "post 7", "post 8", "post 9", "post 10"],
"secondPage" => ["post 11", "post 12", "post 13", "post 14", "post 15", "post 16", "post 17", "post 18", "post 19", "post 20"]
]