Laravel treating decimal as string - laravel

Im trying to make the next eloquent query
$result = $result->where('money','>=',(float)$moneyFilter);
The money column in my database its DECIMAL(11,2), when I run the query it returns an empty array, when I go over php artisan tinker and see the column money, it's a string value "11.1".
I would like to filter the $result collection to have values over $moneyFilter.
Thanks

You need to define in your model which fields need to be cast to a primitive attribute.
protected $casts = ['my_decimal' => 'float'];
There is a really good explanation here:
https://mattstauffer.com/blog/laravel-5.0-eloquent-attribute-casting/
Also there is an explanation in the docs:
https://laravel.com/docs/5.5/eloquent-mutators#attribute-casting

Related

How to get distinct dates from a datetime field

I have this field valid_upto which is a datetime, so if I do:
$dates = Game::where('week', $this->week)
->distinct('valid_upto')
->pluck('valid_upto');
It returns an array like:
["2022-09-08 19:20:00",
"2022-09-11 12:00:00",
"2022-09-11 15:25:00",
"2022-09-11 19:20:00",
"2022-09-12 19:15:00",]
But I only want the date part, like:
["2022-09-08",
"2022-09-11",
"2022-09-12",]
is there a way to do it directly in Laravel's ORM? I don't want to use a rawSelect or similar, I know I could apply DATE('valid_upto') as d in mySQL and Postgres, but I really like to use "general" approaches.
This would work:
foreach ($dates as $i => $d) $dates[$i]=explode(" ", $dates[$i])[0]
$dates = $dates->unique()
But I think its an horrible solution
Something I would like to do, instead of using that foreach, applying a lambda (like in Python) to the Collection and then use the distinct. But I don't know if Laravel has lambdas.
In Laravel you can use Mutators and Casters to determine how certain columns are formatted when you access them. Laravel applies the casting when the model is serialized to json or to an array. So your query could become:
$dates = Game::where('week', $this->week)
->distinct('valid_upto')
->get('valid_upto')
->toArray();
And if you apply a caster on your Game model like so:
protected $casts = [
'valid_upto' => 'datetime:Y-m-d',
];
that should get you a collection of the dates you want in the format you want.

Laravel Array to string conversion error while updating database

I want to update a totcosty field in the User table but it is throwing this error everytime and it is not updating the field
this is the function for execution:
public static function cost(){
$user = User::find($user_id);
$total = Helper::totcost();
// dd($tot_amt);
$user->totcosty = $total;
$user->save();
}
array to string means you are sending an array to the database but db will not accept it you have to explode() the array before sending it to db...
Hope it will help!
If you really want to store an array in some table field, then better declare it as a JSON field. For this, your DB should have support for JSON type columns.
See here how to do this.
Once this is done, you can save arrays in that column, you can assign an array value to the model property and laravel will convert it to JSON while saving and also it will be converted to array while retrieving.

laravel get data without applying casts

I am doing
Model::get()->toArray()
to get all the data from my table but the model has a cast on the dates.
protected $casts = ['date' => 'datetime:D, M d Y'];
I want to be able to get all the data without applying the cast and just the original datetime format. Is there a way to control when the cast is applied.
Laravel 7+
As Sam mentioned for Laravel 7+ you can use:
$model->getRawOriginal('created_at')
You can get all attributes as they are, by using
Model::get()->transform(function ($item) {
return $item->getOriginal();
}))->toArray();
Also can use getOriginal() as
$model->getOriginal('created_at')
on any model to get the original value whenever it's needed.
Note : getOriginal() will include all the $hidden attributes of the model.
getOriginal('date') and getRawOriginal('date') return the unmodified values !
If you want to get the current value without cast, you can use getAttributes()['date']

How to set field for ::create in Laravel?

I use this method to create new row in DB:
$input = $request->all();
return Recipient::create([$input]);
How I can add additional field to $input with an value?
I tried:
$input["user_id"] = Auth::id();
But when I display query INSERT, I can not see field user_id
The problem here is that you probably don't set $fillable property in Recipient model. You should add user_id there:
$fillable = [ ..., 'user_id'];
However merging input is usually not the best way to deal with such things. If you have set relationships properly, it should be possible to do something like this:
Auth::user()->recipients()->create($request->all());
Update
Like #Marcin Nabialek said: add 'user_id' to the $fillable array. And, his solution is cleaner.
Merge
The method merge is what you're looking for: Merge new input into the current request's input array.
$request->merge(['user_id' => Auth::user()->id]);
Recipient::create($request->all());
See the api documentation here: https://laravel.com/api/5.2/Illuminate/Http/Request.html#method_merge
I'm still not sure what exactly you are looking for. Suppose you have 2-3 fields user_id, title, content. For inserting into the database you need to do following:
$input = new Recipient(['title'=>'You title', 'content'=>'Your content']);
$input->save();
It will save two fields with the incremented user_id.
Bro, You're using wrong method,
Try this one:
$input["user_id"] =Auth::user()->id;

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