Updating JSON field of Eloquent model - mysql

So, I have a JSON field in my database. When I access it on my model object, I get a string, so I have to decode it myself. Is it possible to access it like an object? I could define an accessor, but in that case I wouldn't be able to change it.

You can use the Attribute Casting.
Let's assume that in your User model you have an options attribute of type Json so what you can do is adding in your User Model:
protected $casts = [
'options' => 'array',
];
And simply if you want to edit this field you can just do it like so :
$user = App\User::find(1);
$options = $user->options;
$options['key'] = 'value';
$user->options = $options;
$user->save();

Related

Laravel get JSON array from database

What is the best way in Laravel to store an array in your database? And how do I get the same array with a query?
I have a variable that's an array in an array:
$colors = array(array('green'), array('yellow', 'white'));
When I store $colors, my database (column type = json) save it as:
[["green"], ["yellow", "white"]]
But when I try to get it from a query, I couldn't get the same array as $colors.
My query:
$colors = DB::table('colors')
->where('id', '1')
->value('arraycolors');
I hope someone can help how to query an array. Thanks a lot!
You don't need to convert the array data to a JSON string yourself, use the Laravel $casts parameter on your model: https://laravel.com/docs/9.x/eloquent-mutators#array-and-json-casting
You should do something like this in your model:
protected $casts = [
'colors' => 'array',
];
And I recommend changing your migration to text instead of json column like so:
$table->text('colors')->nullable();

Keep sort order of json columns in Laravel after inserting new Key Value pair

I have a key value pair that I am inserting into a model with the following:
public function addContactDetail(Request $request){
$data = $request->all();
$contact_id = $data['contact_id'];
$contact = Contact::find($contact_id);
$details = $contact->details;
$details[$data['label']] = $data['value'];
$contact->details = $details;
$contact->save();
return response()->json($contact);
}
After insert it sometimes puts it randomly in the middle of the object. How do I keep it at the end?
If you are using Laravel 5 or greater version,
Try casting your json column into array in eloquent using mutators. like this.
inside your Contact Model
protected $casts = [
'details' => 'array',
];
By doing so, I guess you will get what you want. Try it and let me know

Retrieve specific data using JSON decode Laravel

I'm new to Laravel. I need to retrieve specific data from the database using the JSON decode. I am currently using $casts to my model to handle the JSON encode and decode.
This is my insert query with json encode:
$request->validate([
'subject' => 'required|max:255',
'concern' => 'required'
]);
$issue = new Issue;
$issue->subject = $request->subject;
$issue->url = $request->url;
$issue->details = $request->concern;
$issue->created_by = $request->userid;
$issue->user_data = $request->user_data; //field that use json encode
$issue->status = 2; // 1 means draft
$issue->email = $request->email;
$issue->data = '';
$issue->save();
The user_data contains {"id":37,"first_name":"Brian","middle_name":"","last_name":"Belen","email":"arcega52#gmail.com","username":"BLB-Student1","avatar":"avatars\/20170623133042-49.png"}
This is my output:
{{$issue->user_data}}
What I need to retrieve is only the first_name, middle_name, and last_name. How am I supposed to achieve that? Thank you in ADVANCE!!!!!
As per the above code shown by you it will only insert data into the database.For retrieving data you can make use of Query Builder as i have written below and also you can check the docs
$users = DB::table('name of table')->select('first_name', 'middle_name', 'last_name')->get();
I will recommend using Resources. It really very helpful laravel feature. Check it out. It is a reusable class. You call anywhere and anytime.
php artisan make:resource UserResource
Go to your the newly created class App/Http/Resources/UserResource.php and drfine the column you want to have in your response.
public function toArray($request) {
return [
"first_name" => $this->first_name,
"middle_name" => $this->middle_name,
"last_name" => $this->last_name
]
}
Now is your controller you can use the UserResource like folow:
public function index()
{
return UserResource::collection(User::all());
}
Or after inserting data you can return the newly added data(f_name, l_name...)
$user = new User;
$user->first_name= $request->first_name;
$user->middle_name= $request->middle_name;
$user->last_name= $request->last_name;
$user->save();
$user_data= new UserResource($user);
return $user_data;

Laravel update json column in postgresql

In postgresql db I have a column type json call it "activities". I would like to add there new (key -> value) pair. Without delete existing data.
At this moment my code look like this:
$user = User::with('userLife')->where(['id' =>$id])->first();
$user->userLife->confirmation_token = null;
$user->userLife->activities = ['emailConfirmed' => Carbon::now()->timestamp];
$user->email_confirmed = true;
$user->push();
In my Model I added:
protected $casts = [
'activities' => 'array',
];
But when I use this code all other data in column is removed and only 'emailConfirmed' appeared there.
So how to do it properly to just add new value in column without removing previous?
Thank you.
You should add it as new element through another variable:
$activities = $user->userLife->activities;
$activities['emailConfirmed'] = Carbon::now()->timestamp;
$user->userLife->activities = $activities;

Inserting JSON to DB Using Model in Laravel

I'm trying to use the model create option and this is my array:
$result = array(
'match_id' => $input['id'],
'score' => $input['score'],
'result' => $input['result'],
'headline' => NULL,
'article' => $input['report'],
'tries' => $input['try'],
'try_amount' => $input['tryquant'],
'conversions' => $input['conv'],
'conv_amount' => $input['convquant'],
'penalties' => $input['pens'],
'pen_amount' => $input['penquant'],
'dropgoals' => $input['dgs'],
'dg_amount' => $input['dgquant']
);
Result::create($result);
The contents of some of these are arrays themselves. eg:
$input['penquant'] = [
"4"
]
When I run my code, it saves the data to the DB simply as Array and throws up the following error:
ErrorException in helpers.php line 703: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
Can someone tell me what I'm doing wrong and how to fix it?
Shouldn't have rushed, forgot to use json_encode.
The best is to use mutators and accessors in your model.
example of mutator
// convert pen_amount from snake case to studly case
// The set...attribute (the ... is you field name which is in studly case) helps transform the data before you save it
// into the database
public function setPenAmountAttribute($value)
{
$this->attributes['pen_amount'] = serialize($value);
}
example of an accessor is
// convert pen_amount from snake case to studly case
// the get...Attribute (the ... is you field name which is in studly case) helps you convert the data back to it original state
public function getPenAmountAttribute($value)
{
return unserialize($value);
}
You can use accessors and mutators for all your fields that you want to save as array. This is elegant. No need to manually use json_encode and decode in your controllers.