How to get db field from class object - laravel

I execute this update statement which works fine.
$g = Group::where([['id', $idgroup], ['admin', $currentUser]]);
$g->update(['admin' => $iduser]);
After this statement I need the field name from my Group object. But with the following statement I get Undefined property: Illuminate\Database\Eloquent\Builder::$name.
$groupname = $g->name;
Group is my model (DB table) which contains the field id, name, admin. How can I get the field name from this object?
Thank you

Without finder it will return you a query builder but when you need to fetch model instance then apply get (for Collection of model) or first(for single model instance) on query builder. For your case you need to call first() method like this
$g = Group::where([['id', $idgroup], ['admin', $currentUser]])->first();
$g->update(['admin' => $iduser]);
Then you can do
$groupname = $g->name;
You can check the details here for retrieving model

If you want to get one record from database then use first():
$g = Group::where([['id', $idgroup], ['admin', $currentUser]])->first();
$g->name; //it will output name
OR
If you want to get all record from database then use get():
$groups = Group::where([['id', $idgroup], ['admin', $currentUser]])->get();
To get name from here you will have to run loop because get() will return a collection
foreach($groups as $g){
$g->name; //it will give name
}

Your $g variable is a Illuminate\Database\Eloquent\Builder which represent a query, not a single object, which means it doesn't have the Group properties. It's very likely you have more than one record under $g, you have two options retrieve all the names fields like this
$g->pluck('name')
This will give you a collection of all the names, or if you're certain there's one single object, you can do $g->first()->name, it will give you the name of the first object (only one if you're sure there is only one object)

Related

Eloquent Collection query - 'WHERE' clause with $value parameter without invoked accessor

I have used some accessors for Model attributes.
And as my knowledge about Accessor in Laravel, it can use to create a virtual attribute based on another attribute value or modify the return value of the existing attribute.
So I create an Accessor with the public method getStatusAttribute to convert the status from integer to string value. For example, my Model has an attribute named is 'status'. In DB, this column is stored with integers like 0,1,2,...
In this method, the return value is a string based on the current status attribute value.
public function getStatusAttribute(int $value): string
{
$statuses = [
1 => 'New',
2 => 'Pending',
3 => 'Canceled'
];
return $statuses[$value];
}
Everything work fined when I retrieve attribute value from the model object entity.
But when I want to retrieve an Eloquent Collection with a specific 'status' attribute value, the $value parameter in the 'where' method expects a string value that is returned from the accessor method, not is an integer value which stored in a database. So the $value parameter would be 'New' or 'Pending' or 'Canceled' instead of 1,2,3.
I want to retrieve a collection that contains an Eloquent Model Object so that I won't use an Illuminate\Support\Facades\DB.
I know I still can retrieve the exact collection with the $value parameter as a string, but I was just wondering if we have another way to skip the accessor in the query of Eloquent Collection?
Please see an example below for more detail about what I expect.
For example, some records in the database look like the below, and the model was named 'DemoModel' :
id
status
1
1
2
3
3
1
4
3
5
2
public function getCanceledEntities($entityId)
{
$canceledEntities = DemoModel::all()->where('status', '=', 3);
if($canceledEntities->isNotEmpty()) {
return $canceledEntities;
}
}
Without an accessor, this query will return a collection containing two entities with id [ 2, 4 ].
But with an accessor (as defined in the model), it can't find a matched entity because the WHERE clause expects that the 3rd parameter is 'Canceled' instead of 3.
My alternative method is to use a string 'Canceled' in the 'where' clause. However, I still want to use the value stored in a database for the query, and I think maybe the framework has another way to write an Eloquent Collection query without invoking an accessor.
Any suggestions are always welcome.

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;

Join query in laravel with data manipulation send to view

I am having 2 tables, users and profiledetails
I am able to run Join query and access the data and send to view.
But when I am manipulation the field 'dob' (date format) in profiledetails table. No Success, Please check the code below ,
webpagesConroller:
$users = DB::table('users')
->join('profiledetails', 'users.id', '=', 'profiledetails.user_id')
->select('users.*', 'profiledetails.dob')
->get();
$age = $users->dob->diffInYears(Carbon::now());
return view('webpages.index',compact('users'))->with($age);
View:
<li class="cate_head">Age : {{ $age}}</li>
Error:
Trying to get property of non-object
I have model Profiledetails added the mutators as below,
public function getAge(){
return $this->dob->diffInYears(Carbon::now());
}
public function getDOB(){
return $this->dob->format('d-m-Y');
}
Can I not use this method on another controller for Ex- webpagesController, If yes How.
Since you are using a raw query, the data returned is not an object but an array with the data.
Also you did not limit the query, meaning it could return multiple rows.
You'll probably need to get the data from the $users as:
//with the possibily of multiple rows. Index is the row which has to be used
$users[index]['dob']
//when you are sure it only returns one row
$users[0]['dob'] // or $users['dob'] not sure as of the moment
You want to check the differences with Carbon.
So you will probably need to make a Carbon object of the dob result and check it against the Carbon::now.
$age = Carbon::createFromFormat('Y-m-d', $users[0]['dob'])->diffForHumans();
// diffForHumans() uses the local time
Note that this only gets the age for one row (the index or the first because of [0]).
If you want to do it for every row use a for or foreach where you set the $users->age for every $user. But as these are not object/models but raw data, this will not work.
Hope this helps your question a bit

Get Attribute from Elequent where clause

So I have the following where clause where I am searching the name "Gold" inside of my tier table.
$tier = Tier::where(['name' => 'Gold'])->get(['id']);
dd($tier);
When I do the above the "id" is listed inside of the attributes but when I do as below it gives me
Undefined property: Illuminate\Database\Eloquent\Collection::$id
dd($tier->id);
All I want is to get the Id of the record where the name is "Gold".
To get actual model you should use first() instead of get(). Because there are potentially multiple rows that match get() will return a collection.
$tier = Tier::where(['name' => 'Gold'])->first(['id']);
dd($tier->id);
If you really need only the id there's even a simpler function to that, pluck().
It will get one attribute from the first result:
$id = Tier::where(['name' => 'Gold'])->pluck('id');

Doctrine toarray does not convert relations

I followed doctrine documnetation to get started. Here is the documentation.
My code is
$User = Doctrine_Core::getTable("User")->find(1);
when I access relations by $User->Phonenumbers, it works. When I convert User object to array by using toArray() method, it does not convert relations to array. It simply display $User data.
Am I missing something?
By using the find method you've only retrieved the User data which is why the return of toArray is limited to that data. You need to specify the additional data to load, and the best place to do this is usually in the original query. From the example you linked to, add the select portion:
$q = Doctrine_Query::create()
->select('u.*, e.*, p.*') // Example only, select what you need, not *
->from('User u')
->leftJoin('u.Email e')
->leftJoin('u.Phonenumbers p')
->where('u.id = ?', 1);
Then when toArray'ing the results from that, you should see the associated email and phonenumber data as well.
I also noticed an anomaly with this where if you call the relationship first then call the ToArray, the relationship somehow gets included. what i mean is that, taking your own eg,
$User = Doctrine_Core::getTable("User")->find(1);
$num= $User->Phonenumbers->office; // assumed a field 'office' in your phone num table
$userArray = $user->toArray(true);
In the above case, $userArray somehow contains the whole relationship. if we remove the $num assignment it doesn't.
am guessing this is due to doctrine only fetching the one record first, and it's only when you try to access foreign key values that it fetches the other related tables

Resources