Need suggestion in query builder of Laravel 9 application - mysql

How to avoid foreach-loop because Laravel query builder is used to get a single record detail.
When I tried without foreach-loop, the following error occurred "Property [name] does not exist on this collection instance".
Controller
public function show(Student $student)
{
$result = DB::table('students')
->select('*')
->where('id', "=" ,$student['id'])
->get();
foreach($result as $studentData){}
return view('student.show', ['studentData' => $studentData]);
}
Blade View
{{ $studentData->name}}

->get() always returns a Collection, even if there's only one match. If you only want the first record, you can use ->first() instead.

Do you really have to use raw queries? I assume Student is a Laravel Model, in that case, you should be able to use Student::find($id) to get the model directly.

Related

Laravel "->where(like) issue"

I have this code
$users = array();
$users_to_add = User::all()->where('unit', 'LIKE', '%'.$request->unit.'%');
But i get nothing on $users_to_add. The like doesn't work. What am i missing?
all() actually runs a query to get all users. Therefore, your where() call is on the Collection (PHP), not the Query Builder (SQL).
You'll want to use get() but make sure you declare your query conditions prior to calling it.
get() will execute the query, with your defined conditions, and return a collection of results.
User::where('unit', 'LIKE', '%'.$request->unit.'%')->get();

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 Select Query Accessing Returned Data

I've been working with Laravel for a short time, and am confused about accessing data retrieved from queries. I'm trying to save data to variable but am getting the following:
Trying to get property of non-object
Queries tried:
$data = DB::table('table_1')->select('user_id', 'email')->where('email', '=', Input::get('email_address'))->get();
// also tried
$data = DB::table('table_1')->where('email', '=', Input::get('email_address'))->pluck('user_id');
// accessing data
$userID = $data->user_id;
Both return the same.
To elaborate a little bit, ->get() will return a Collection. You might iterate over it as an array, but you can profit from methods that this class offers. pluck is one of these.
That's why $userID = $data->user_id; wouldn't work.
first() did the trick, rather than get().
$data = DB::table('table_1')->select('user_id', 'email')->where('email', '=', Input::get('email_address'))->first();

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()

Laravel Fluent queries - How do I perform a 'SELECT AS' using Fluent?

I have a query to select all the rows from the hire table and display them in a random order.
DB::table('hire_bikes')->order_by(\DB::raw('RAND()'))->get();
I now want to be able to put
concat(SUBSTRING_INDEX(description, " ",25), "...") AS description
into the SELECT part of the query, so that I can select * from the table and a shortened description.
I know this is possible by running a raw query, but I was hoping to be able to do this using Fluent or at least partial Fluent (like above).
How can I do it?
You can actually use select AS without using DB::raw(). Just pass in an array into the select() method like so:
$event = Events::select(['name AS title', 'description AS content'])->first();
// Or just pass multiple parameters
$event = Events::select('name AS title', 'description AS Content');
$event->title;
$event->content;
I tested it.
Also, I'd suggest against using a DB:raw() query to perform a concatenation of your description field. If you're using an eloquent model, you can use accessors and mutators to perform this for you so if you ever need a limited description, you can simply output it in your view and not have to use the same query every time to get a limited description. For example:
class Book extends Eloquent
{
public function getLimitedDescriptionAttribute()
{
return str_limit($this->attributes['description'], $limit = 100, $end = '...');
}
}
In your view:
#foreach($books as $book)
{{ $book->limited_description }}
#endforeach
Example Output (not accurate to limit):
The description of this book is...
I'd also advise against using the DB facade because it always utilizes your default connection. If you're querying a secondary connection, it won't take this into account unless you actively specify it using:
DB::connection('secondary')->table('hire_bikes')->select(['name as title'])->get();
Just to note, if you use a select AS (name AS title) and you wish to update your the model, you will still have to set the proper attribute name that coincides with your database column.
For example, this will cause an exception because the title column does not exist in your database table:
$event = Events::select('name AS title')->first();
$event->title = 'New name';
$event->save(); // Generates exception, 'title' column does not exist.
You can do this by adding a DB::raw() to a select an array in your fluent query. I tested this locally and it works fine.
DB::table('hire_bikes')
->select(
array(
'title',
'url',
'image',
DB::raw('concat(SUBSTRING_INDEX(description, " ",25),"...") AS description'),
'category'
)
)
->order_by(\DB::raw('RAND()'))
->get();
select(array(DB::raw('latitude as lat'), DB::raw('longitude as lon')))