Reputation: 29278
So I'm coming across an issue with QueryBuilder
cloning. He's my situation, I need to run 3 separate queries, all based off a single "BaseQuery":
$baseQuery = $model->selectRaw("column")->whereNull("deleted_at");
$query1 = clone($baseQuery);
$query1Results = $query1->where("condition", "=", 0)->get();
$query2 = clone($baseQuery);
$query2Results = $query2->where("condition2", "=", 1)->get();
$query3 = clone($baseQuery);
$query3Results = $query3->where("condition3", "=", 0)->get();
By the time I get to $query3
, it has 3 where statements. Substituting $query3 ... get()
with $query3 ... ->toSql();
shows these results:
SELECT `column` FROM `models` WHERE `deleted_at` IS NULL AND `condition` = ? AND `condition2` = ? AND `condition3` = ?;
It seems that even though I am defining each $queryX
as a clone of $baseQuery
, the additional ->where()
clause is being applied to each of the queries. I've tried doing the clone()
before appending any of the ->where()
clauses, but that doesn't have any affect.
Is there a way to clone()
something and ensure that it creates a new instance? It looks like clone()
isn't separating $baseQuery
from $queryX
, so the ->where()
s are being applied to every subsequent copy, even though each should be a new query with only the ->whereNull()
clause.
Another interesting point is that running
\Log::info($baseQuery == $queryX);
After each modification returns true
(===
is false
though)
Upvotes: 1
Views: 337
Reputation: 163788
You should use scopes here.
Local scopes allow you to define common sets of constraints that you may easily re-use throughout your application. For example, you may need to frequently retrieve all users that are considered "popular". To define a scope, simply prefix an Eloquent model method with scope
public function scopeBase($q)
{
return $q->selectRaw('column')->whereNull('deleted_at');
}
Then just do something like this:
$query1Results = $model->where('condition', 0)->base()->get();
$query2Results = $model->where('condition2', 1)->base()->get();
$query3Results = $model->where('condition3', 0)->base()->get();
Upvotes: 1