I'd like to change a data before saving I have a date where I don't need seconds only minutes, and I want the seconds to be 00 all the time. I tried Laravel's prepareForValidation() method in my request class, but it turned out it does not affect value stored in database. I also tried backpack's modifyField() but I couldn't find a way to modify value before store or update.
What's the best way to perform this? Using Laravel7 and Backpack 4.1
I don't know if there's a specific backpack way of doing it, but you can use a mutator on your model to modify the value before it gets saved to the database.
In your case, if your fieldname is "date_time" you could do something like:
class MyModel extends Model {
setDateTimeAttribute ($value) {
$value = Carbon::parse($value)->second(0);
$this->attributes['date_time'] = $value;
}
}
This has the benefit that the mutation will occur every time your date_time attribute is updated - whether you update it through your Backpack Crud or from some other method.
References:
Laravel Mutators: https://laravel.com/docs/7.x/eloquent-mutators#defining-a-mutator
Modifying Dates with Carbon: https://carbon.nesbot.com/docs/#api-settersfluent
Related
I was not happy with the default created_at date format in my database table so I decided to create Accessors which will simply change my date format. But I found out that Accessors is not running. I tried to use it on another column but it doesn't change my output. then I use dd($value) so it can stop in accessor but I found out that it didn't. I am getting my data from the database and the accessor is been bypassed.
my accessor in model class is:
public function getCreatedAtAttribute($value)
{
dd($value);
}
But it does not effect anything as I am getting my output of :
$case=Allcase::with('donner')->get();
print_r($case);
and also no effect to created_at:
You can customize the actual attribute value in this way
public function getCreatedAtAttribute()
{
return Carbon::parse($this->attributes['created_at'])->format('Y-m-d');
}
Now, you can get your data and print it. You can show the differences now
$case = Allcase::with('donner')->get();
print_r($case);
I use in my laravel 5.5 app Model::updateOrCreate(), it works, but by 1 parameter I wish to do something only if entry is creating and not updating model, is this possible?
The updateOrCreate returns a model instance where you can check for recent creation
An example could be the following pseudo code
$model = Model::updateOrCreate($data);
if($model->wasRecentlyCreated) {
// Do logic only when the model was created
}
Is it possible to use an Accessor for comparison in Laravel 4, for example:
class User extends Eloquent {
// define Accessor
public function getSpecialNameAttribute()
{
return 'Joda';
}
}
$User = User::where('gender','=','male')->where('specialName','=','Joda');
?
Yes, you can use it to filter query results:
User
::where('gender','=','male')
->get()
->filter(function($item) {
return $item->specialName === 'Luke';
});
(!) Note that filtering will be applied after quering DB, so in case of big data this solution will have performance issues.
For more details I've googled for you this Collections tutorial.
Also I suggest query scopes may be useful to complete your task in best way.
No, you cannot use it this way.
When you use:
$user = User::where('gender','=','male')->where('specialName','=','Joda')->get();
you will try to compare specialName column in database with Joda string.
You cannot use accessor here, because accessor may be very complicated and then Laravel would need to take all data from table in database (for example 100000 records) and calculate accessors for all of them to get for you only records you need (for example 1 record).
You can use accessor only when you have object instance, and you won't be able to use it when querying database.
After saving a new model / active record in Yii2, I'm scheduling a job on the filesystem. I do this in afterSave and I would like to update the record with the job id of the scheduler I get back.
But when I call $this->update() in the model after setting the correct property to the job id, no update is happening. Using update() in an afterSave() is probably a bad idea, but what would then be the right way to tackle this?
You can use updateAttributes($attributes)
This method is a shortcut to update() when data validation is not
needed and only a small set attributes need to be updated.
You may specify the attributes to be updated as name list or
name-value pairs. If the latter, the corresponding attribute values
will be modified accordingly. The method will then save the specified
attributes into database.
Note that this method will not perform data validation and will not
trigger events.
http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#updateAttributes()-detail
I see 2 options there:
Create additional internal field in the model, something like private $task_sended = false; In afterUpdate set task_sended = true and check It
if (!$this->task_sended){
//send task to scheduler
$this->task_sended = true;
}
Use DAO command to update model
\Yii::$app->db->createCommand()->update(self::tableName(), $update, ['id'=>$this->id])->execute();
I've just picked up laravel after deciding to move to a php framework. I'm retrieving a result set of articles from a database using an eloquent query:
$posts = Article::select(array('articles.id','articles.article_date','articles.image_link','articles.headline','articles.category', 'articles.published'));
this works fine and results come out as expected.
However I now want to change the format of the article date from the mysql date format to another for the entire collection.
I thought about iterating through the object and changing using the usual php methods but wondered if there was an easier way to manipulate the data either when initiating the query or en mass with the object itself.
I've looked at mutators? but wasnt sure if this was appropriate or how to implement
Any help, pointers appreciated
You're right, mutators are the way to go. (Laravel 3 syntax)
Getter and Setter documentation for Eloquent models
public function get_article_date()
{
return date('d-m-Y H:i:s', strtotime($this->get_attribute('article_date'));
}
Getting the attribute
$articles = Articles::get(array(
'article_date',
'image_link',
'headline',
'published'
));
foreach($articles as $article)
{
echo $article->article_date;
}
Every time you get the date from your model it will run through the mutator first returning your modified result.
Absolutely no need to run raw queries for something like this.
EDIT got set and get mixed up... more coffee needed (answer edited)
Im not sure if this is working, but give it a try
$posts = Article::select(array('articles.id',DB::raw('CAST(articles.article_date as date)'),'articles.image_link','articles.headline','articles.category', 'articles.published'));