Related
I'm a bit new to this, and was originally trying to check if my model was returning results with isEmpty(), but thought I'd try count() instead, then I came across the following:
I've got the following code, which returns data from my model:
$results = Game::where('code', '=', $code)->with('genre', 'creator')
And whether I use first() or get() combined with count(result) or $results->count() I get different values, and I'm not sure why.
when using ->first()
dd($results->count()) = 11930 // Number of rows in the db
when using ->get()
dd($results->count()) = 1 // What I'd expect the query to return
when using ->first()
dd(count($results)) = "count(): Parameter must be an array or an object that implements Countable"
when using ->get()
dd(count($results)) = 1
I don't understand 1) why when using first, the count is the same as every row in the db. 2) Why count() can't be used with first().
Is anyone able to shed some light as to why I can't use count on first as I'd like to?
Update:
I'm also not able to use ->isEmpty() with ->first() but can with ->get()...?
When I try using it with first, I get Illuminate\Database\Query\Builder::isEmpty does not exist.
Disclaimer: I'm not sure why your database count and your results count aren't the same, however I can shed some light on the different types of count.
Game::where('code', '=', $code)->count();
This is being called on a query builder instance. It is run on the database query, without selecting all the rows. Check out the title Aggregates here: https://laravel.com/docs/5.7/queries
Game::where('code', '=', $code)->get()->count();
As soon as your use get() laravel selects the rows, boots them all as models, and creates a collection. This count is on the collection (a bit like an array) so just gets the number that are returned (i.e. if they are paginated or anything like that it will just get that amount). Check out Count here.
Game::where('code', '=', $code)->first()->count();
This is being run on the first returned model... unless you've written it, a default laravel model won't have a count() method.
count($results)
Finally, count() when not a class method is just the default php function that returns the length of an array or other object (documentation).
First of all,
get() returns collection of objects while first() returns modal object of query.
$results = Game::where('code', '=', $code)->with('genre', 'creator')
dd($results->count()) = 11930 // Number of rows in the db
when using ->get()
$results = Game::where('code', '=', $code)->with('genre', 'creator')->get()
dd($results->count()) = 1
because it has collection, which contains numbers of objects of database data. As ->count getting only one collection so it returns 1.
I may be missing something extremely trivial, but is it possible to retrieve specific columns/fields from models when grabbing a collection rather then returning the entire item's fields?
Here is my query:
$items = Items::where('visible', true)->take(10)->get();
This obviously returns each item in there entirety, including unique id's, and other fields i dont want to be fetched... how can i refine this query to just select specific fields from the models?
Laravel Query Builder get() function receives array of columns which you need to fetch.
$items = Items::where('visible', true)->take(10)->get(['column_1', 'column_2']);
Use select() method to do this:
$items = Items::select(['column_1', 'column_2']'])->where('visible', true)->take(10)->get();
Source: Latavel Database Query Builder
Laravel Query Builder gives a huge flexibility to write this types of query.
You can use select(), get(), all() methods.
Items::where('visible', true)->take(10)->get('col_1', 'col_2');
OR
Items::select('col_1', 'col_2')->where('visible', true)->take(10)->get();
Items::select(['col_1', 'col_2'])->where('visible', true)->take(10)->get();
$user_emails = ["email_1#domain.com", "email_2#domain.org"];
$users = Users::whereIn("email", $user_emails);
The table for users also has a phone column for each user. What's the best way to get a list/array of the phone number as an array?
$users->all()->phone(); // Like (which is not correct)
Try to use get() like :
$users = Users::whereIn("email", $user_emails)->get(['phone'])->toArray();
Or also pluck() like :
$users = Users::whereIn("email", $user_emails)->pluck('phone')->all();
Hope this helps.
Use pluck method to fetch a specific column's values and then use toArray on returned Collection object to get results as an array.
$phoneNumbers = Users::whereIn("email", $user_emails)->pluck('phone')->toArray();
You can get all column data with get()
Example:
$user = $user::where('email', $user_emails)->get();
You can get the list with foreach loop method.
lets say I have 7 columns in table, and I want to select only two of them, something like this
SELECT `name`,`surname` FROM `table` WHERE `id` = '1';
In laravel eloquent model it may looks like this
Table::where('id', 1)->get();
but I guess this expression will select ALL columns where id equals 1, and I want only two columns(name, surname). how to select only two columns?
You can do it like this:
Table::select('name','surname')->where('id', 1)->get();
Table::where('id', 1)->get(['name','surname']);
You can also use find() like this:
ModelName::find($id, ['name', 'surname']);
The $id variable can be an array in case you need to retrieve multiple instances of the model.
By using all() method we can select particular columns from table like as shown below.
ModelName::all('column1', 'column2', 'column3');
Note: Laravel 5.4
You first need to create a Model, that represent that Table and then use the below Eloquent way to fetch the data of only 2 fields.
Model::where('id', 1)
->pluck('name', 'surname')
->all();
Also Model::all(['id'])->toArray() it will only fetch id as array.
Get value of one column:
Table_Name::find($id)->column_name;
you can use this method with where clause:
Table_Name::where('id',$id)->first()->column_name;
or use this method for bypass PhpStorm "Method where not found in App\Models":
Table_Name::query()->where('id','=',$id)->first()->column_name;
in query builder:
DB::table('table_names')->find($id)->column_name;
with where cluase:
DB::table('table_names')->where('id',$id)->first()->column_name;
or
DB::table('table_names')->where('id',$id)->first('column_name');
last method result is array
You can use get() as well as all()
ModelName::where('a', 1)->get(['column1','column2']);
From laravel 5.3 only using get() method you can get specific columns of your table:
YouModelName::get(['id', 'name']);
Or from laravel 5.4 you can also use all() method for getting the fields of your choice:
YourModelName::all('id', 'name');
with both of above method get() or all() you can also use where() but syntax is different for both:
Model::all()
YourModelName::all('id', 'name')->where('id',1);
Model::get()
YourModelName::where('id',1)->get(['id', 'name']);
To get the result of specific column from table,we have to specify the column name.
Use following code : -
$result = DB::Table('table_name')->select('column1','column2')->where('id',1)->get();
for example -
$result = DB::Table('Student')->select('subject','class')->where('id',1)->get();
use App\Table;
// ...
Table::where('id',1)->get('name','surname');
if no where
Table::all('name','surname');
If you want to get a single value from Database
Model::where('id', 1)->value('name');
Also you can use pluck.
Model::where('id',1)->pluck('column1', 'column2');
You can use Table::select ('name', 'surname')->where ('id', 1)->get ().
Keep in mind that when selecting for only certain fields, you will have to make another query if you end up accessing those other fields later in the request (that may be obvious, just wanted to include that caveat). Including the id field is usually a good idea so laravel knows how to write back any updates you do to the model instance.
You can get it like
`PostModel::where('post_status', 'publish')->get(['title', 'content', 'slug', 'image_url']`)
link
you can also used findOrFail() method here it's good to used
if the exception is not caught, a 404 HTTP response is automatically sent back to the user. It is not necessary to write explicit checks to return 404 responses when using these method not give a 500 error..
ModelName::findOrFail($id, ['firstName', 'lastName']);
While most common approach is to use Model::select,
it can cause rendering out all attributes defined with accessor methods within model classes. So if you define attribute in your model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get the user's first name.
*
* #param string $value
* #return string
*/
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}
And then use:
TableName::select('username')->where('id', 1)->get();
It will output collection with both first_name and username, rather than only username.
Better use pluck(), solo or optionally in combination with select - if you want specific columns.
TableName::select('username')->where('id', 1)->pluck('username');
or
TableName::where('id', 1)->pluck('username'); //that would return collection consisting of only username values
Also, optionally, use ->toArray() to convert collection object into array.
If you want to get single row and from the that row single column, one line code to get the value of the specific column is to use find() method alongside specifying of the column that you want to retrieve it.
Here is sample code:
ModelName::find($id_of_the_record, ['column_name'])->toArray()['column_name'];
If you need to get one column calling pluck directly on a model is the most performant way to retrieve a single column from all models in Laravel.
Calling get or all before pluck will read all models into memory before plucking the value.
Users::pluck('email');
->get() much like ->all() (and ->first() etc..) can take the fields you want to bring back as parameters;
->get/all(['column1','column2'])
Would bring back the collection but only with column1 and column2
You can use the below query:
Table('table')->select('name','surname')->where('id',1)->get();
If you wanted to get the value of a single column like 'name', you could also use the following:
Table::where('id', 1)->first(['name'])->name;
For getting multiple columns (returns collection) :
Model::select('name','surname')->where('id', 1)->get();
If you want to get columns as array use the below code:
Model::select('name','surname')->where('id', 1)->get()->toArray();
If you want to get a single column try this:
Model::where('id', 1)->first(['column_name'])->column_name;
I'm stuck on a simple task.
I just need to order results coming from this call
$results = Project::all();
Where Project is a model. I've tried this
$results = Project::all()->orderBy("name");
But it didn't work. Which is the better way to obtain all data from a table and get them ordered?
You can actually do this within the query.
$results = Project::orderBy('name')->get();
This will return all results with the proper order.
You could still use sortBy (at the collection level) instead of orderBy (at the query level) if you still want to use all() since it returns a collection of objects.
Ascending Order
$results = Project::all()->sortBy("name");
Descending Order
$results = Project::all()->sortByDesc("name");
Check out the documentation about Collections for more details.
https://laravel.com/docs/5.1/collections
In addition, just to buttress the former answers, it could be sorted as well either in descending desc or ascending asc orders by adding either as the second parameter.
$results = Project::orderBy('created_at', 'desc')->get();
DO THIS:
$results = Project::orderBy('name')->get();
Why?
Because it's fast! The ordering is done in the database.
DON'T DO THIS:
$results = Project::all()->sortBy('name');
Why?
Because it's slow. First, the the rows are loaded from the database, then loaded into Laravel's Collection class, and finally, ordered in memory.
2017 update
Laravel 5.4 added orderByDesc() methods to query builder:
$results = Project::orderByDesc('name')->get();
While you need result for date as desc
$results = Project::latest('created_at')->get();
In Laravel Eloquent you have to create like the query below it will get all the data from the DB, your query is not correct:
$results = Project::all()->orderBy("name");
You have to use it in this way:
$results = Project::orderBy('name')->get();
By default, your data is in ascending order, but you can also use orderBy in the following ways:
//---Ascending Order
$results = Project::orderBy('name', 'asc')->get();
//---Descending Order
$results = Project::orderBy('name', 'desc')->get();
Check out the sortBy method for Eloquent: http://laravel.com/docs/eloquent
Note, you can do:
$results = Project::select('name')->orderBy('name')->get();
This generate a query like:
"SELECT name FROM proyect ORDER BY 'name' ASC"
In some apps when the DB is not optimized and the query is more complex, and you need prevent generate a ORDER BY in the finish SQL, you can do:
$result = Project::select('name')->get();
$result = $result->sortBy('name');
$result = $result->values()->all();
Now is php who order the result.
You instruction require call to get, because is it bring the records and orderBy the catalog
$results = Project::orderBy('name')
->get();
Example:
$results = Result::where ('id', '>=', '20')
->orderBy('id', 'desc')
->get();
In the example the data is filtered by "where" and bring records greater than 20 and orderBy catalog by order from high to low.
Try this:
$categories = Category::all()->sortByDesc("created_at");
One interesting thing is multiple order by:
according to laravel docs:
DB::table('users')
->orderBy('priority', 'desc')
->orderBy('email', 'asc')
->get();
this means laravel will sort result based on priority attribute. when it's done, it will order result with same priority based on email internally.
EDIT:
As #HedayatullahSarwary said, it's recommended to prefer Eloquent over QueryBuilder. off course i didn't encourage using QueryBuilder and we all know that each has own usecases.
Any way so why i wrote an answer with QueryBuilder? As we see in eloquent documents:
You can think of each Eloquent model as a powerful query builder allowing you to fluently query the database table associated with the model.
BTWS the above code with eloquent should be something like this:
Project::orderBy('priority', 'desc')
->orderBy('email', 'asc')
->get();