Eloquent whereHas and With() - laravel

What im trying is to get my AppNamespace, AppModule and AppController. So i use Laravel 5.2 with eloquent and run:
$this->namespaceModel->whereTitle( $this->namespace )
->whereHas( 'modules', function ( $q )
{
$q->whereTitle( $this->module );
} )
->whereHas( 'modules.controllers', function ( $q )
{
$q->whereTitle( $this->controller );
} )
->first();
This gives me a false or true depending on the results, but not the record itself. I've used a with() too but that doesnt return a record IF the whereHas() returns true. How can i fix that?

Alternatively you can use joins on that query like this:
$this->namespaceModel->whereTitle( $this->namespace )
->join( 'modules', 'namespaces.id', '=', 'modules.namespace_id')
->join( 'controllers', 'modules.id', '=', 'controllers.module_id')
->where( 'modules.title', $this->module )
->where( 'controllers.title', $this->controller )
->select('namespaces.*')
->with('modules', 'modules.controllers')
->first();

Related

Laravel query groubBy condition

I have a dB query where I would like to groupBy() only when conditions are met without using union because of pagination.
Unfortunately groupBy() seems to only work when called on the entire query outside of the loop.
This was made for dynamic filtering from $filterArr. Depending on the array I need to select from different columns of the table.
When the $key=='pattern' I would need the distinct results from its column.
the query looks something like this
select `col_1`, `col_2`, `col_3`
from `mytable`
where (`color` LIKE ? or `pattern` LIKE ? or `style` LIKE ?)
group by `col_2` //<< i need this only for 'pattern' above and not the entire query
Heres the model:
// $filterArr example
// Array ( [color] => grey [pattern] => stripe )
$query = DB::table('mytable');
$query = $query->select(array('col_1', 'col_2', 'col_3'), DB::raw('count(*) as total'));
$query = $query->where(function($query) use ($filterArr){
$ii = 0;
foreach ($filterArr as $key => $value) {
if ($key=='color'){
$column = 'color';
}else if ($key=='style'){
$column = 'style';
}else if ($key=='pattern'){
$column = 'pattern';
$query = $query->groupBy('col_2'); // << !! does not work
}
if($ii==0){
$query = $query->where($column, 'LIKE', '%'.$value.'%');
}
else{
$query = $query->orWhere($column, 'LIKE', '%'.$value.'%');
}
$ii++;
}
});
$query = $query->orderBy('col_2', 'asc')->simplePaginate(30);
I think you can simplify your code a bit:
$query = DB::table('mytable');
$query = $query->select(array('col_1', 'col_2', 'col_3'), DB::raw('count(*) as total'));
$query = $query->where(
collect($filterArr)
->only(['color','style','pattern'])
->map(function ($value, $key) {
return [ $key, 'like', '%'.$value.'%', 'OR' ];
})->all()
)->when(array_key_exists('pattern', $filterArr), function ($query) {
return $query->groupBy('col_2');
});
$query = $query->orderBy('col_2', 'asc')->simplePaginate(30);

Laravel 5.6 Or Query Multiple in where

This is my filter query function
$keywords = [];
foreach($columns as $key => $value){
$keywords[] = [$key, 'LIKE', '%'.$value.'%'];
}
$query= $this->model ->orderBy('name', 'asc')->where('is_deleted', 0)->Where($keywords);
if($status=="yes")
$query= $query->where('status',1);
$query= $query->get();
return $query;
For the above function, i got the following query
select * from stores where is_deleted = 0 and status = 1 AND (name LIKE %r% AND address LIKE %r%) order by name asc
But i need Or instead of ANd in the like query
select * from `stores` where `is_deleted` = 0 and `status` = 1 AND (`name` LIKE %r% or `address` LIKE %r%) order by `name` asc
Please tell in which place i need to change?
You can use Where and orWhere.
$query= $this->model->orderBy('name', 'asc')->where('is_deleted', 0)->
orWhere($key, 'LIKE', '%'.$value.'%');
You have to group those orWhere() queries in one where() clause
$query = $this->model->where([
['is_deleted' => 0],
['status' => $status]
])
->where(function ($query) use($columns) {
foreach($columns as $key => $value) {
$query->orWehre($key, 'like', "%$value%");
}
})
->orderBy('name');

write orwhere for multi tables in eloquent

I am using eloquent as ORM and I want to use where in multi-table like this:
$raw_query = EntityCity::with(['province']);
$raw_query = $raw_query->where(function ( $q ) use ( $search_data ) {
$q->where('city.title' , 'like' , "%$search_data%")
->orwhere('province.title' , 'like' , "%$search_data%");
});
}
$this->data[ 'result_list' ] = $raw_query->limit($this->per_page)
->orderByDesc("time_insert")
->offset(( $page_num - 1 ) * $this->per_page)
->get();
However, I encounter the following error:
Message: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'province.title' in 'where clause' (SQL: select count(*) as aggregate from city where (city.title like %fars% or province.title like %fars%))
If I comment the orwhere it works.
So how can you write this with orwhere?
Instead of:
$raw_query = $raw_query->where(function ( $q ) use ( $search_data ) {
$q->where('city.title' , 'like' , "%$search_data%")
->orwhere('province.title' , 'like' , "%$search_data%");
});
}
you should use:
$raw_query = $raw_query->where(function($q) {
$q->where('city.title', 'like', "%$search_data%")
->orWhereHas('province', function ( $q ) use ( $search_data ) {
$q->where('province.title' , 'like' , "%$search_data%");
});
});
Notice that the where .. orWhereHas was wrapped here in additional where and this gives you confidence you can add any other conditions as for example selecting only active cities:
$raw_query = $raw_query->where(function($q) {
$q->where('city.title', 'like', "%$search_data%")
->orWhereHas('province', function ( $q ) use ( $search_data ) {
$q->where('province.title' , 'like' , "%$search_data%");
});
})->where('active', 1);
Try to use orWhereHas:
$raw_query = $raw_query->where('city.title', 'like', "%$search_data%")
->orWhereHas('province', function ( $q ) use ( $search_data ) {
$q->where('province.title' , 'like' , "%$search_data%");
});

how whereBetween handle to this query

I want to use whereBetween to handle this query
select * from schedules where now() BETWEEN start and end
thank for your attentions
You can do like this
$schedules = DB::table('schedule')->select('id', 'name')
->whereBetween( DB::raw('now()'), [$startDate, $endDate])
->get();
You can write this query as:
$schedules = DB::table('schedules ')->select( 'id','name')
->where( DB::raw('now()'), '>=', 'startDateField' )
->where( DB::raw('now()'), '<=', 'endDateField' )
->get();
Also as per comment by #Devon, you can use whereBetween:
$schedules = DB::table('schedules ')->select( 'id','name')
->whereBetween( DB::raw('now()'), array('startDateField', 'endDateField')
->get();

With query Issue in Eloquent

I have following query which works fine and gives result for StatusType
AddOnModel::with('StatusType')->get();
But when I write below, it does not bind StatusType Records
AddOnModel
::select(\DB::Raw('A.AddOnID, A.AddOn, Count(R.AddOnID) as Total'))
->from( 'tblAddOn as A' )
->with('StatusType')
->leftjoin( 'tblrevenue as R', \DB::raw( 'R.AddOnID' ), '=', \DB::raw( 'A.AddOnID' ) )
->groupBy("A.AddOnID", "A.AddOn")->get();
The part which does not work is this one: ->with('StatusType')
Am I doing something incorrectly?
Here is the Model
class AddOnModel extends Model {
public $table = 'tbladdon';
public $primaryKey = 'AddOnID';
public $timestamps = true;
public function StatusType() {
return $this->hasOne('\StatusTypeModel', 'StatusTypeID', 'StatusTypeID');
}
}
you can do this as a solution, make toArray() method in AddOn model, make that method returns what you need id, name, etc, like this:
return [
'id' => $this->id,
'StatusType' => this->StatusType
]
You use with() after ->leftjoin may be this will affect. Try below code:
AddOnModel::with('StatusType')
->select(\DB::Raw('A.AddOnID, A.AddOn, Count(R.AddOnID) as Total'))
->from( 'tblAddOn as A' )
->leftjoin( 'tblrevenue as R', \DB::raw( 'R.AddOnID' ), '=', \DB::raw( 'A.AddOnID' ) )
->groupBy("A.AddOnID", "A.AddOn")
->get();
Hpoe this will work for you.

Resources