I have an input field that will provide me the 24 hour format time like 16:30, 18:22, 13:50 etc. So how to set migration column for this.
I read already documentation but not did not understand.
As #M Khalid Junaid has suggested, you should define a mutator for your attribute on your model to modify the value of a normal timestamp.
So firstly, you need to create the column in the migration:
$table->timestamp('your_column_name');
Then, you can create your mutator on your model just like any method. We are going to use Carbon to play around with the format. Keep in mind that the name of the mutator needs to be the camelCase of your column name:
protected function yourColumnName(): Attribute
{
return new Attribute(
get: fn ($value) => Carbon::parse($value)->format('H:i'),
);
}
Related
I am using laravel
I want to change the value of a column according to a specific condition.
if a condition is satisfied in wherehas then change the value of specific column to 1 let's say.How could i do it.
if i can call a function in the model inside the wherehas function to change the value how could I do it ??
i can iterate the result set using a 2 for loops and change it, however I want to decrease the complexity by changing the value while retrieving the data
Course::with('stages','stages.levels')->whereHas('stages.levels', function($query)use ($levelsarray){
$query->wherenotIn('id', $levelsarray);
here I want to change a column value in table levels
})->first();
Here is a general way,
Assuming you have Three models, Course, Stage, Level
When you are retrieving data from Level model, add an accessor,
For more info click here.
Eg:
On Level.php model,
public function getColumnNameAttribute($value) // replace ColumnName with column name
{
//write application logic here.
return $value;
}
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']
really need your help here. ( I don't know what I want is possible on Eloquent )
Lets pretend this Relationship: One user can have many Childs
Note: Ignore problems in the code, this is just an example.
Now lets add some code into it.
// Return HasMany Object Instance from Eloquent.
$hasMany = $user->childs()
// Perform Mass Update.
$hasMany->update(['born_at' => Carbon::now])
So far nothing wrong with it, the first line returns an HasMany Object ( Documentation )
The problem is that Mass Updating touches my Model's timestamps ( created_at, updated_at ) and specially for this update I don't want it to do that.
Disabling it on the Model is not an option for me I do use the timestamp touch normally but I don't want to use in this case.
Neither I want to iterate over the Collection ( $user->childs ) because I have many rows to update and its an overhead to generate one query for each Model to update.
What I expect for an answer to this question: Simple, I just want an way to turn off the timestamps to do the mass updating or something like that.
( Normally on a single Model you can disable it like this: $model->timestamps = false, but this will not work here because hasMany instance does not have this attribute. )
You could set the property default of the model to false. So in you're model class you will have:
public $timestamps = false;
But this will always disable the timestamps until je use:
$model->timestamps = true;
In case someone finds this through Google:
One possible solution is to Fallback to the base QueryBuilder:
(new Child)
->newQuery()
->toBase()
->where('parent_id', $model->id)
->update([
'born_at' => Carbon::now,
]);
Of course, one could just use here something like DB::table(...)...
I store in my database a date format like this:
2017-02-22 16:55:40
I added it to my database like this:
Carbon::now();
I need to check if 4 hours passed since this date.
How I can do this? I couldn't figure out how I can convert this format into Carbon or timestamp.
If you are using Laravel and the date is a Carbon instance from a Model you have access to the whole Carbon API.
You can use the Difference API of Carbon for this specific purpose.
echo $model->thedate->diffInHours($now, false);
If your model does not threat the date as a carbon instance you can cast it by adding the date to the dates array of the current model like so
protected $dates = [
'field_name',
];
Check out Date casting for more information
Update with an explicit example
$user = User::first();
// This will return the difference in hours
$user->created_at->diffInHours(Carbon\Carbon::now(), false);
You can convert it to a Carbon object with:
Carbon::parse('2017-02-22 16:55:40');
I am trying to get the number of new users for each week using the created_at column. I am trying to use the whereBetweensyntax but it always return 0 even when it is suppose to return otherwise.
{{ DB::table('users')
->whereBetween('created_at', array(date("Y/m/d h:i:s", strtotime('sunday last week')), date("Y/m/d h:i:s", strtotime('saturday this week'))))->count(); }}
Any suggestions?
The query itself should work as written, though you might want to verify that created_at is a column of either timestamp, date, or datetime type. When you created the users table, did you use a migration to create your users table, and if so, did you specify $table->timestamps();? Or did you manually define the created_at column, and perhaps set it to a string?
A couple other (unrelated) suggestions:
• It appears that you're running this query in a view, echoing the count using blade. This logic would be better handled elsewhere, perhaps in your User model, and the result passed to the view by the controller.
• You can simplify your query using PHPs DateTime object, replacing your date(...strtotime...) with date_create(...):
$usersThisWeek = User::whereBetween(
'created_at', array(
date_create('sunday last week'),
date_create('saturday this week')
))->count();