I'm working on Laravel 4. As I knew, I can do subquery:
Project::whereIn('project_id', function($q) {
$q->select('project_id')
->from('company')
->whereNull('deleted_at');
});
I found complications, that I can't use scope in subquery and disable soft_delete make me change source code so much.
I wish it was:
Project::whereIn('project_id', function(&$q) {
$q = Company::select('project_id')->getQuery();
});
Now, I can add scope, disable soft_delete easily.
I tried, and found a solution, that I must change Laravel's Database\Query\Builder code, function whereInSub, line 786.
call_user_func($callback, $query = $this->newQuery());
to:
$query = $this->newQuery();
call_user_func_array($callback, array(&$query));
It's harmful to modify Laravel framework's vendor. So I want to ask how to do it safely.
Sorry because my bad English.
Thank you for reading.
You can create a custom query builder and use it like this.
My Custom Query Builder:
In any Model overwrite the method newBaseQueryBuilder() and return an instance of your own query builder
Oooh! This is quite a tricky one since your model would extend
Eloquent
, thenEloquent
usesIlluminate\Database\Query\Builder
.But what I noticed is that
Eloquent
is actually an alias inapp/config/app.php
file. So what you can do is following these steps.Illuminate\Database\Query\Builder
toMyQueryBuilder
with your customwhereInSub()
.Illuminate\Database\Eloquent\Model
toMyModel
and make ituse
yourMyQueryBuilder
.Eloquent
alias inapp/config/app.php
to your newMyModel
class.Something like this:
MyQueryBuilder.php:
MyModel.php:
app/config/app.php:
Note that I put long lists of
use
up there because "use" keyword does not get inherited. Also I did not putMyQueryBuilder
andMyModel
in a namespace for the sake of simplicity. Myuse
list might also be different from yours depending on Laravel versions we use, so please check the uses too.