Pluck together with first using Query builder - laravel

If I want to get get name of first user in database using eloquent I can do something like that:
$user = User::select('name')->first()->pluck('name');
// or $user = User::first()->pluck('name');
echo $user;
to get only name of this user as string.
However If I try the same using only query builder:
$user = DB::table('users')->select('name')->first()->pluck('name');
echo $user;
I get exception:
Call to undefined method stdClass::pluck()
But without using first it will work:
$user = DB::table('users')->select('name')->where('id',1)->pluck('name');
echo $user;
Is it not possible to use pluck with first using query builder or am I doing something wrong?
PS. Of course I know that I can display any property using $user->name without using pluck but I'm just curious why using Eloquent it works and using Query Builder it works only when not having both first and pluck

You don't want to use pluck with first, because it's redundant:
$query->first() // fetch first row
->pluck('name'); // fetch first row again and return only name
So use only pluck:
$query->pluck('name');
It does all you need.
But there's more.
Under the hood first and pluck run 2 separate queries, so:
$query->where(..)->orderBy(..)->first() // apply where and orderBy
->pluck('name'); // no where and orderBy applied here!
So it's not only redundant to use first before pluck, but also it causes unexpected results.
You can chain those methods on Eloquent query, since it returns a collection (get) or model (first), but Query\Builder returns just an array (get) or stdObject (first). That's why you couldn't do the same oon the query builder.

In Laravel 5.1+, you can use the value method.
From the docs:
If you don't even need an entire row, you may extract a single value
from a record using the value method. This method will return the
value of the column directly:
$email = DB::table('users')->where('name', 'John')->value('email');
This is how it works behind the scenes in the Builder class:
/**
* Get a single column's value from the first result of a query.
*
* #param string $column
* #return mixed
*/
public function value($column)
{
$result = (array) $this->first([$column]);
return count($result) > 0 ? reset($result) : null;
}

Try this one:
$user = User::pluck('name')->first();
echo $user;

Current alternative for pluck() is value().
To get first occurence, You can either use
DB::table('users')->value('name');
or use,
DB::table('users')->pluck('name')->first();

Related

Error Call to a member function where() on array Laravel

I want to do filtering from the data that I display, but there is a problem when I add where to my data.
the plan in the future I want to add if isset $request name, date and others. but was constrained at this one point.
Thank you for helping to answer in advance
$matchs =Matchs::where('type', 'sparring')->where('status','Pending')->whereNull('deleted_at')->get()->toArray();
$data=[];
foreach ($matchs as $key) {
$lawan = Matchs::where('id', $key['id'])->first()->ToArray();
$pertandingan = Sparring::where('match_id', $key['id'])->first()->ToArray();
$dua_arah = MatchTwoTeam::where('match_id', $key['id'])->first()->ToArray();
$tim = Team::where('id', $dua_arah['home_team'])->first()->ToArray();
$transfer['name']=$tim['name'];
$transfer['city']=$lawan['city'];
$transfer['field_cost']=$pertandingan['field_cost'];
$transfer['referee_cost']=$pertandingan['referee_cost'];
$transfer['logo_path']=$tim['logo_path'];
$transfer['nama_lapangan']=$lawan['nama_lapangan'];
$transfer['date']=$lawan['date'];
array_push($data,$transfer);
array_push($data,$pertandingan);
}
$data->where('name', 'LIKE', '%'.'football'.'%')->get()->toArray();
$data = array_search('football', array_column($data, 'name'));
$tittle="Sparring";
return view('mode.sparring',[
'tittle' => $tittle,
'data' => $data,
]);
You are trying to call where in an array which is not possible.
As you can see in the first line of your code you are calling where method in your model class. Like Matchs::where('type', 'sparring'), this is possible because Matchs is a Model class.
Now you can run where even if you are using array. You can convert that day in collection and then use array on that collection.
As below:
collect($data)->where('name', 'football')->toArray();
Here collect() will convert the $data array to collectio and then run the where() method in collectio then toArray() will change it back to array. But unfortunately there is no like operator possible in collection class. See the list of available method in Laravel collection here: https://laravel.com/docs/8.x/collections#available-methods
There is a way to do what you are trying to do. As far as I understand you want to filter the Matches where the Team name has footbal in it. You can do it like this:
Matchs::where('type', 'sparring')
->where('status','Pending')
->whereNull('deleted_at')
->whereHas('team', function($team) {
return $team->where('name', 'LIKE', '%'.'football'.'%')
})
->get()
->toArray();
So, here we can get the only those Mathes that has the Team that has the name contains football.
Few suggestion for you as seems you are new in Laravel:
Model name should be singular instead of plural, so the model class Matchs should be Match. Your name for team's model is Team is correct.
Avoid using toArray() because you won't need it. When you call get() it will return object of collection which more readable and powerful then array in most cases.
The code I suggested to use the like using whereHas will only work if you have propery defined your team relation in your Matchs class. So, defining your relationships in model is also important. If you do so, you don't even need the for loop and all those where in other model in that loop. You can do it in one query with all the relationships.

use a custom function inside a laravel select

I have a query that needs to use a custom function like is showed below.
The problem is that one of the parameters is a value of another field from the same query.
The function is "calcula_distancia" and "$ofps[0]->latitude" and "$ofps[0]->longitude" are fields from a previus query.
The function needs 4 parameters and the last two are field from $necps that is beeing selected, but I can not retrieve the value from it using just 'participantes.latitude' or even without cotes. It passes a string only, to the function.
So, how can I pass the value from this fields beeing selected to the function?
Tryed to use RAW but not work.
Sorry for the big question. thanks! :-)
use App\Classes\MinhasFuncoes;
$mf = new MinhasFuncoes();
$necps = DB::table('necessidades_part')->where('necessidades_part.id_part',"<>",$id_part)
->where(function($query) use ($searchValues){
foreach ($searchValues as $value) {
if(strlen($value)>3){
$query->orwhere('obs','like','%'.($value).'%')
->orwhere('necessidades.descricao','like','%'.($value).'%')
->orwhere('categorias.descricao','like','%'.($value).'%');
}
}
})
->join('participantes','necessidades_part.id_part','=','participantes.id')
->join('necessidades','necessidades_part.id_nec','=','necessidades.id')
->join('categorias','necessidades.id_cat','=','categorias.id')
->join('unidades','necessidades.id_unid','=','unidades.id')
->select('participantes.id as id_part','participantes.nome_part','participantes.latitude',
'participantes.longitude','participantes.nome_part','necessidades_part.id as id_nec_part',
'necessidades_part.id_nec','necessidades_part.quant','necessidades_part.data',
'necessidades_part.obs','necessidades.descricao as desc_nec',
'categorias.descricao as desc_cat','unidades.descricao as desc_unid',
$mf->calcula_distancia($ofps[0]->latitude,$ofps[0]->longitude,'participantes.latitude',
'participantes.longitude').' as distancia')
->orderBy('data','desc')
->paginate(10);
you can not execute your PHP function inside of your DB query. you should use MySQL function instead of that or you should fetch results from the database then map your result just in PHP

Remove Limit From Eloquent Query

How can I remove the limit/offset from the below query?
$query = TestModel::where('a', 'b')->limit(100);
$query->removeLimit();
I'm using a query from another module and I don't want to change the code.
You can reset the $limit property:
$query = TestModel::where('a', 'b')->limit(100);
$query->limit = null;
$unlimited = $query->get();
$query->getQuery()->limit = null;
One can reset the limit by passing the null value to the limit method.
$query->limit(null);
Works both with Eloquent\Builder and Query\Builder.
The simple answer to your question is - you cannot. Because you have already filtered the result set to a limit of 100 tuples.
What is the reason for you to avoid the change in code in the Model? Because what #Dhruv has suggested is the correct way to achieve what you want to.
In fact, if you still want to keep the code intact. You can rather define another function in your model this way and use it internally in your old function:
public function newFunction(){
return TestModel::where('a', 'b')->get();
}
public function oldFunction(){
return $this->newFunction()->limit(100);
}
Keeping your code consistent, then use newFunction() in your Controller to do whatever you want to.
get(): To get all record from table use get():
$query = TestModel::where('a', 'b')->get();
limit(): To limit the number of results returned from the query
$query = TestModel::where('a', 'b')->limit(10)->get();

Laravel Eloquent ORM - How to get the all the properties of afrom/of a collection in a array?

$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.

How to select specific columns in laravel eloquent

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;

Resources