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);
Related
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
I am trying to use wasChanged and wasRecentlyCreated of models in laravel project but both of them are false in the below code
$saved=$project->accessInfo()->updateOrCreate(['type'=>$request->type],['value'=>$data]);
dd($project->accessInfo[0]->wasChanged(),$project->accessInfo[0]->wasRecentlyCreated,$project->wasRecentlyCreated,$project->wasChanged());
//here is my relation in Project model
public function accessInfo()
{
return $this->hasMany('Modules\Project\Models\ProjectAccessInfo', 'project_id');
}
also below code returns error
dd($project->accessInfo->wasChanged(),$project->accessInfo()->wasRecentlyCreated)
//No such method or attribute in both cases
//Call to undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::wasChanged()
Thanks in advance for your help.
getChanges - Get the attributes that were changed.
getDirty - Get the attributes that have been changed since last sync.
When you want to know if the model has been edited since it was queried from the database, or isn't saved at all, then you use the ->isDirty() function.
I have many "get" mutators which decrypt data so that it can be readable in the view. These mutators are the names of the fields in the DB. Most of these work except for 2. The only difference with these 2 mutators is that the mutator function names contains numbers.
Example of a mutator which works:
public function getDateOfBirthAttribute($value)
{
return empty($value) ? '' : decrypt($value);
}
Examples of mutators which do NOT work:
public function getAddressLine1Attribute($value)
{
return empty($value) ? '' : decrypt($value);
}
public function getAddressLine2Attribute($value)
{
return empty($value) ? '' : decrypt($value);
}
Name of fields in table:
address_line_1
address_line_2
The very strange thing about all this is when the response is NOT json, the mutator works as expected and decrypts the field. (e.g. using return view('view.name', compact($user))), however when I put this data into a JSON response (e.g. return response()->json([$user]);, the 2 address line mutators don't work and returns the field untouched.
I have tried adding return "test" to these 2 mutators to see if it is even hitting the function but it is not.
Why in this instance does JSON stop the mutator from working? Could it be an issue with numbers in the function name? May I have to rename my fields in the DB?
I can't verify this now, but i think it may be related to the way laravel computes snake_case and camel_case.
Basically, when you request a field like $user->address_line_1, laravel transforms the field in camelCase (AddressLine1) and checks for a custom accessors, it finds it and returns the correct modified value.
However, when the model is serialized into Json, it does the opposing operation: it tries to detect which field needs to be modified by looking at the accessors. So, it finds the getAddressLine1Attribute and transforms it into snake_case.. yielding address_line1, a wrong field.
The basic problem here is that both address_line_1 and address_line1 have the same camelCase representation, so it's impossible to reliably reverse the transformation to camelCase.
An hack you could try is to define the accessor as getAddressLine_1Attribute, but it won't work when accessing the field directly ($user->address_line_1)
You could define it to use the previously defined accessors, so you don't have code repetition:
public function getAddressLine_1Attribute($value)
{
return $this->getAddressLine1Attribute($value);
}
public function getAddressLine1Attribute($value)
{
return empty($value) ? '' : decrypt($value);
}
EDIT: my theory has been confirmed by some testing with the camel_case() and snake_case() helper functions
I want to check if certain columns in database are changed.
the update code in my controller goes like this:
$tCustomer = TCustomer::withTrashed()->findOrFail($id);
$tCustomer->update(request()->all());
How do I incorporate it with the ->isDirty() function?
I tried adding it after $tCustomer->update(request()->all()); but it always returns false:
$dirty = $tCustomer->getDirty('payment_method_id');
do I have to add isDirty() before or right after the update?
You can uuse fill() instead of update(), check for isDirty(), then save(). This way you can take advantage of the mass injectable fields.
$myModel->fill($arrayLikeinUpdate);
if ($myModel->isDirty()) {
// do something
}
$myModel->save();
You have to use observers, you can use updating() eloquent model event for before saving the model or updated() after saving model, you just have to add below code in your TCustomer model:
public static function boot(){
static::updated(function($tCustomer){
if($tCustomer->isDirty('field_name')){
//This code will run only after model save and field_name is updated, You can do whatever you want like triggering event etc.
}
}
static::updating(function($tCustomer){
if($tCustomer->isDirty('field_name')){
//This code will run only before saving model and field_name is updating, You can do whatever you want like triggering event etc.
}
}
isDirty returns a bool, so you'd use it with a conditional to check if a given models attributes have changed. Example:
// modify an attribute
$myModel->foo = 'some new value';
....
// do other stuff
...
// before the model has been saved
if ($myModel->isDirty()) {
// update model
$myModel->save();
}
So the check needs to be done before you update (save) the model.
Calling update saves the model with the given attributes in one call so you wouldn't use isDirty in that context.
I have several fields in a form with dates and times ('dd-mm-yyyy', 'hh:mm').
When I want to save the form I use my own function to convert it for MySQL ('yyyy-mm-dd', 'H:i:s') via date() which I added to save() in Laravel Model Class.
But where is single place where I can put the same function to format output (SELECT queries)?
There is no single function in Laravel for data output. find(), findOrNew(), findOrFail(), ... - there are in different classes so I cant use single place to add the formatting function.
Is there any proper place to put formatting function?
You can use Laravel Date Mutator. Just put the following method in your Eloquent Model:
Suppose your have a table user in your database with expireDate column. then define this field in your model.
class User extends Eloquent {
protected $dates = ['expireDate'];
}
Just Replace FirstName with your database column name.
Then you can use laravel Carbon class to format your result.
$user = User::find(1);
return $user->expireDate->format('d-m-Y');
For more reference please read the http://laravel.com/docs/4.2/eloquent#date-mutators
Just add this to AppServiceProvider#register:
Carbon::setToStringFormat('d/m/y');
Now you can just echo $model->created_at and everything’s formatted correctly.
In App directory, create a new directory. Let call it "libraries",
then create a php file "CustomFunction.php" or whatever, this has to be a class as well, then put your function in this class.
So you have
class CustomFunction{
static function dateFormat(){
}
}
in App/libraries/
Then in App/start/global.php
Iside classloader on line 14, as below, add the path to your new folder:
ClassLoader::addDirectories(array(
app_path().'/libraries'
));
Then in your composer.json file, add:
"app/libraries" to "autoload" array.
Then in your view you can easily do this:
{{ CustomFunction::dateFormat() }}