Query builder laravel with and select - mysql

I want to show "cars.name" in result.
I need to use "cars.name" value to order later
$this->model
->select("pieces.*", "cars.name")
->where('cars_id', $carId)
->with('cars')
->has('cars', '>=', 1);
How can I do that?

You can try to do it this way by passing a closure function in with():
$this->model
->select("pieces.*")
->where('cars_id', $carId)
->with('cars'=> function ($query) {
$query->select('id','name');
}])
->has('cars', '>=', 1);
It will only select id and username from other table.
Remember that the primary key (id in this case) needs to be the first param in the $query->select() to actually retrieve the necessary results.

the first you have built is just a query, then it needs to be retrieved on the server, use get() and you will see error message. Need more info about the relation between pieces and cars to help. Try it -
$this->model::whereHas('cars',function(builder $query)use($cardId){
$query->where('cars_id', $carId);})->has('cars', '>=', 1)->with('cars')->get();
then obtain cars name via denamic property of a relation

Related

getting records by id and querying there relation with 'wherebetween' using Laravel and eloquent

i'm trying to get all measurements from a certain recorder between a certain timespan.
If i remove the "->wherebetween()" part of the query and view the results then I get all the sensors of that recorder and all related measurements of that sensor.
But I'm not able to execute a wherebetween on the relation.
query in the controller
public function getChart(Request $request) {
$sensorCollection = Sensor::where('recorder_id', $request->recorder_id)
->with('getMeasurementsRelation')
->wherebetween('getMeasurementsRelation', function ($query) use ($request) {
return $query->wherebetween('timestamp',[$request->start_chart, $request->end_chart]);})
->get();
}
Relationship in Sensor model
public function getMeasurementsRelation() {
return $this->hasmany('App\Models\measurement', 'sensor_id', 'id');}
You can use callback in with method like below.Since you have not mentioned start and end chart value format .So i assume its Y-m-d format .if not let me know in comment i can modify my answer according to your need
$sensorCollection = Sensor::where('recorder_id', $request->recorder_id)
->with(['getMeasurementsRelation'=>function($query)use($request){
$startChart=\Carbon\Carbon::createFromFormat('Y-m-d',$request->start_chart)->startOfDay();
$endChart=\Carbon\Carbon::createFromFormat('Y-m-d',$request->end_chart)->endOfDay();
$query->wherebetween('timestamp',[$startChart, $endChart]);
}])
->get();

Filter With() in Query Scope

Controller
$r = \App\User::whereIn('id', $user_ids)->withPosts($category_id)->get();
User model
public function scopeWithPosts($query, $category_id)
{
return $query->with('posts')->where('category_id', $category_id);
}
I have been at this for too many hours now.
I am trying to use with() along with an query scope to add an extra filter to the relationship.
However it gives me the error " category_id not existing in users table"? What am I missing?
Laravel 6
The problem you are experiencing is that you are expecting the with('posts') function to return a query that is relative to the Posts ORM model. It won't, it will still return a reference to the original query. What you will find is that the with function returns $this, so you'll always get the original query.
What you are attempting is a SQL query to find the User, followed by another SQL query to get all the Post records of that user, with those posts filtered by category. So
SELECT * FROM Users WHERE id=?;
SELECT * FROM Posts WHERE user_id = ? AND category_id = ?
To do that in the Eloquent relationship, you need to subquery, like so:
return $query->with(['posts' => function ($q) use ($category_id) {
$q->where('category_id', $category_id);
}]);
Please comment if you need further info and I'll edit my answer.

Eloquent Query, possible Join

I have three models: driver, designation and dpsObject, with the following replationships:
driver->hasMany(dpsObject)
driver->belongsTo(Designation)
designation->hasMany(Driver)
dpsObject->belongsTo(Driver)
I'm trying to write a query to return a list of dpsObject records that correspond to the values of three user inputs, which are: a date range(From and To) holding the values of an EntryDate field in the dpsObject and a Designation input, holding the value of a Designation_name field in the Designation object.
Currently this is my Query:
$dps = dpsObject::where([['entryDate', '>=', $from],
['entryDate', '<=', $to]]);
$from and $to hold the request values gotten from the form user's submit.
I need to complete the query to capture the Designation name of a driver that that has dpsObject records. The challenge is that the designation_name field does not exist on the dpsObject model but only on the driver and designation models. This is how I want to maintain the database model. I think I need to be using a join or something similar, but I'm not sure how to go about it.
What is the best way to write such a query?
Kind regards
You can use nested whereHas():
$dpsObjects = dpsObject::whereBetween('entryDate', [$from, $to])
->whereHas('driver', function ($q) use($designationName) {
$q->whereHas('designation', function ($q) use($designationName) {
$q->where('designation_name', $designationName);
});
})
->get();
Here, designation and driver are belongsTo() relationships.

Laravel 5 Eloquent ORM select where - array as parameter

I'm getting grade_id from the database:
$grade_id = DB::table('grades')->where('teacher_id',$teacher_id)->select('grade_id')->get();
and then I want to use that grade_id array in the where eloquent clause so I run
$home_feed = Home::join('home_grade', 'home_grade.home_id', '=', 'homes.id')
->whereIn('grade_id', $grade_id)
->get();
but when I run this I'm getting an error: Object of class stdClass could not be converted to string
What could be the problem? Thanks guys.
Depending on laravels version your $grade_id is either an array or a collection of objects. What you need is an array or a collection of values.
You can achieve that using the pluck() method insted of select() like IzzEps suggested.
But you can get the same result by passing a subquery to the whereIn() method:
$gradeSubquery = DB::table('grades')->where('teacher_id',$teacher_id)->select('grade_id');
$home_feed = Home::join('home_grade', 'home_grade.home_id', '=', 'homes.id')
->whereIn('grade_id', $gradeSubquery)
->get();
This way you will run only one query instead of two.
Update: Before version 5.2 you have to use lists() instead of pluck(). And the whereIn() method doesn't accept a Builder as second parameter. To get the same query you would need to use a closure:
$home_feed = Home::join('home_grade', 'home_grade.home_id', '=', 'homes.id')
->whereIn('grade_id', function($query) use($teacher_id) {
$query->from('grades')
->where('teacher_id', $teacher_id)
->select('grade_id');
})
->get();
your first query is returning a collection, not the grade_id.
Try this instead: $grade_id = DB::table('grades')->where('teacher_id',$teacher_id)->pluck('grade_id');
Using lists worked.
$grade_id = Grade::where('teacher_id', $teacher_id)->lists('grade_id');
They return an array instead of a collection
You need to create the array correctly. To do this use two functions that Eloquent work with: pluck() and toArray(). Look at example below:
$grade_id = DB::table('grades')->where('teacher_id',$teacher_id)->pluck('grade_id')->toArray();

Laravel Fluent add select()s in separate places?

//Earlier in the code, in each Model:
query = ModelName::select('table_name.*')
//Later in the code in a function in a Trait class that is always called
if ($column == 'group_by')
{
$thing_query->groupBy($value);
$thing_query->select(DB::raw('COUNT('.$value.') as count'));
}
Is there a way to append or include a separate select function in the eloquent query builder?
The actual ->select() is set earlier and then this function is called. I'd like to add the count column conditionally in this later function that has the query passed into it.
For future reference, you can use the addSelect() function.
It would be good to have in the documentation, but you'll find it here in the API: http://laravel.com/api/4.2/Illuminate/Database/Query/Builder.html#method_addSelect
Yeah you just insert the block you wanna execute as a function....according to the documentation on Parameter Grouping , you can do like so...by passing the Where a function...
This code below probably wont do what you want, but, its something for you to build off of, and play around with.
DB::table('users')
->where('name', '=', 'John')
->orWhere(function($query)
{
$query->group_by($value);
->select(DB::raw('COUNT('.$value.') as count'));
})
->get();
Try this:
$thing_query->groupBy($value)->get(DB::raw('COUNT('.$value.') as count'));
Also,if you are just trying to get the count and not select multiple things you can use ->count() instead of ->get()