I'm running the following query that has a with() relation.
$logbook_objectives = self::whereIn('lobjective_id', $logbook_objectives_ids)
->with(['objective' => function($q) use ($course_objective_ids){
$q->select(['objective_id', 'objective_code', 'objective_name'])
->whereIn('objective_id', $course_objective_ids)
->whereIn('objective_parent', $course_objective_ids, 'or');
}])
->withCount(['entryObjectives' => function ($q) use ($learner_id) {
$q->where('created_by', $learner_id);
}])
->get();
Sometimes the the returned 'objective' field is null because of the rules within the with function. How do I remove the results that have objective = null?
I tried using ->whereHas('objective') before the ->get() but it doesn't change anything. Is there another way to evaluate if the with function returned null keeping the same query?
Solutions I have on my head:
Use join instead, so I can evaluate null results in the same query.
Use a foreach look verifying if the objective field is null and remove found results from my returned list.
If objective table has 'objective_id' or any other key as primary key then place that key in whereNotNull just as given below:
$logbook_objectives = self::whereIn('lobjective_id', $logbook_objectives_ids)
->with(['objective' => function($q) use ($course_objective_ids){
$q->select(['objective_id', 'objective_code', 'objective_name'])
->whereIn('objective_id', $course_objective_ids)
->whereIn('objective_parent', $course_objective_ids, 'or')->whereNotNull('objective_id');
}])
->withCount(['entryObjectives' => function ($q) use ($learner_id) {
$q->where('created_by', $learner_id);
}])
->get();
The solution I found was to use a whereHas together with the with function. The query would be:
$logbook_objectives = self::whereIn('lobjective_id', $logbook_objectives_ids)
->with(['objective' => function($q) use ($course_objective_ids){
$q->select(['objective_id', 'objective_code', 'objective_name'])
->whereIn('objective_id', $course_objective_ids)
->whereIn('objective_parent', $course_objective_ids, 'or');
}])
->whereHas('objective', function($q) use ($course_objective_ids){
$q->select(['objective_id', 'objective_code', 'objective_name'])
->whereIn('objective_id', $course_objective_ids)
->whereIn('objective_parent', $course_objective_ids, 'or');
})
->withCount(['entryObjectives' => function ($q) use ($learner_id) {
$q->where('created_by', $learner_id);
}])
->get();
In that case only rows that the objective exists will be returned.
Related
So my code is
$categories=Category::where('user_id', $store->id)->whereHas('childrenCategories', function($q) use ($id){
$q->where('user_id', $id);
})->orwhereHas('products', function($q) use ($id) {
$q->where('auth_id', $id);
})->with('products', 'childrenCategories')->latest()->get();
I want to get all children categories with and products with given id but this code doesn't seem to work. As children categories with user_id other than id are also being returned. Sorry, I am relatively new to Laravel. And I thought this would be a good platform to ask. Also, I can share the relationships if you want me to.
I solved this with the following. Thanks, #lagbox for your time.
$categories = Category::with(['childrenCategories' =>
$childrenClosure = function ($query) use ($id) {$query->where('user_id', $id);}, 'products'
=> $productsClosure = function ($query) use ($id) {$query->where('auth_id', $id);}])
->where('user_id', $store->id)
->where(function ($query) use ($childrenClosure, $productsClosure) {$query->whereHas('childrenCategories', $childrenClosure)
->orWhereHas('products', $productsClosure);})
->latest()
->get();
I am not able to find any perfect solution for it.
Controller:
$servicerequest = ServiceRequest::selectRaw('count(id) as totalservice,max(created_date) as last_service,service_provider_id,id,service_id,account_id,service_request,created_date')->with(['account' => function($first) use ($keyword) {
$first->select('id', 'restaurant_name')->orderBy('restaurant_name', 'DESC');
}])
->with(['serviceProvider' => function($query) use ($keyword) {
$query->select('id', 'company_name');
}])->groupBy('account_id')
->orderBy('company_name', 'DESC')
->paginate(100);
I need an order by on model relation table field and that effect on main table data. because it's and one to one relationship so no need to order by on the inside.
Like I need to the orderby whole on relations data.
Collection:
You must make join your relation table to used orderBy relation table.
You can try this code.
$servicerequest = ServiceRequest::selectRaw('count(id) as totalservice, max(created_date) as last_service,service_provider_id,id,service_id,account_id,service_request,created_date, SERVICEPROVIDERTABLE.company_name')
->join('serviceProvider', 'SERVICEPROVIDERTABLE.id', '=', 'SERVICEREQUESTTABLE.service_provider_id')
->with([
'account' => function ($first) use ($keyword) {
$first->select('id', 'restaurant_name')
->orderBy('restaurant_name', 'DESC');
}
])
//->with([
// 'serviceProvider' => function ($query) use ($keyword) {
// $query->select('id', 'company_name');
// }
//])
->groupBy('account_id')
->orderBy('SERVICEPROVIDERTABLE.company_name', 'DESC')
->paginate(100);
i hope this works.
The query is retrieving wrong data, must retrieve only departamento not null. Can anyone help me?
Code:
$banca = Banca::with(['trabalho.membrobanca.departamento' => function($query) use ($d) {
$query->where('id', $d);
}])->get();
$banca = collect($banca)
->unique('trabalho_id')
->values()
->all();
The diagram with relationship.
You can put the filter on the memrobanca table and filter on null values.
$banca = Banca::with([
'trabalho.membrobanca' => function($query) use ($d) {
$query->where('departamento_id', $d)
->whereNotNull('departamento_id')
->with('departamento');
}
])
->get();
You can use Laravel has() function. It will return return Banca where departamento is not null
$banca = Banca::with(['trabalho.membrobanca.departamento' => function($query) use ($d) {
$query->where('id', $d);
}])
// has function will return banca if banca has non-null departamento
->has('trabalho.membrobanca.departamento')
->get();
Check this:
https://laravel.com/docs/5.4/eloquent-relationships#querying-relationship-existence
Currently, the function below works correctly, however, the ->has('alerts') returns the entire array of alerts including all relationship data. I want to return only certain columns from that relationship.
public function getMatches()
{
$matches = Criteria::select('id')
->has('alerts')
->with(['alerts.location' => function($w){
$w->select('id');
}])
->with('alerts.user.companies')
->where('user_id', Auth::id())
->get();
return Response::json(array(
'matches' => $matches,
'status' => '200'
)
);
}
The columns that I'd like to return can be accessed within blade format (note the pivot that is also used):
#foreach($matches as $match)
#foreach($match->alerts as $alert)
{{$alert->pivot->criteria_id}}
{{$alert->pivot->alert_id}}
{{$alert->price_value}}
{{$alert->location->type}}
{{$alert->category}}
{{$alert->description}}
{{$alert->category}}
{{$alert->user->companies->first()->logo->url('thumb')}}
{{$alert->pivot->viewed}}
#endforeach
#endforeach
I have tried the following:
public function getMatches()
{
$matches = Criteria::select('id')
->has(['alerts' => function ($q){
$q->select('id', 'pivot.criteria_id');
}])
->with(['alerts.location' => function($w){
$w->select('id');
}])
->with('alerts.user.companies')
->where('user_id', Auth::id())
->get();
}
But I'm presented with the following error:
strpos() expects parameter 1 to be string, array given
The error occurs when the following function is added to the has() function:
->has(['alerts' => function ($q){
$q->select('id', 'pivot.criteria_id');
}])
Any help as to how I can select said fields from the 'alerts' table and the according relationships I'd be highly appreciative.
In your code you have something like this:
->has(['alerts' => function ($q){
//...
}])
It should be like this:
->whereHas('alerts', function ($q){
//...
})
You don't want to use has or whereHas for that. The has functions are only to filter the result based on a relation. To only select certain columns use with()
$matches = Criteria::select('id')
->has('alerts')
->with(['alerts' => function($q){
$q->select('id', 'pivot.criteria_id');
}, 'alerts.location' => function($w){
$w->select('id');
}])
->with('alerts.user.companies')
->where('user_id', Auth::id())
->get();
I have a table named answers and its columns are id, answers, batch, candidate_id. I want to get all candidates that has no record of answers under batch number of 1.
Is there a way to add condition to this statement (this is in my candidate model) ?
return $this->has('answers', '=', 0)->get();
I tried this way but it didn't work:
return $this->has('answers', '=', 0)->whereBatch(1)->get();
You need whereHas:
$this->whereHas('answers', function ($q) {
$q->whereBatch(1);
}, '=', 0)->get();
Btw this is exactly the same as calling has with closure as 5th param:
$this->has('answers', '=', 0, 'and', function ($q) {
$q->whereBatch(1);
})->get();