Update Field After Save in Laravel - laravel

I have a questions database table with the field featured_image and my questions model has an attachOne file named featured_image_file. The featured_image_file column doesn't get saved to the database, so for my API, I am updating the field featured_image after save.
I saw some answers to this question on other posts that didn't work. Eventually, I figured it out and my resulting code is this:
public function save(?array $options = [], $sessionKey = null)
{
$user = BackendAuth::getUser();
$this->user_id = $user->id;
// throw new ApplicationException(json_encode($this));
parent::save($options);
$url = $this->featured_image_file->getPath();
$this->featured_image = $url;
parent::save($options);
}
Is this the proper method to modify when inserting into the database? Is it okay to call parent::save($options) twice?

Related

Stuck at Error = Method Illuminate\Database\Eloquent\Collection::save does not exist

Trying to save data while open page but stuck at error :
"Method Illuminate\Database\Eloquent\Collection::save does not exist."
I have 2 database :
Buffalodata
Buffalomilkrecord
From 2nd table i need to get the avg of totalmilk and update the same to main database (1). This help me to show updated avgmilk data on dashboard front page.
Route:
Route:: get('buffalo-details', 'App\Http\Controllers\BuffalodataController#buffalodetails');
BuffalodataController Controller :
public function buffalodetails()
{
$buffalidforavgmilk = Buffalodata::groupBy('buffaloID')->get('buffaloID')->pluck('buffaloID')->toArray();
foreach ($buffalidforavgmilk as $id )
{
$milkperid = Buffalomilkrecord::where('buffaloID', $id)->sum('totalmilk');
$avgbuffalocount = Buffalomilkrecord::where('buffaloID',$id)->count();
$getavg = $milkperid / $avgbuffalocount;
$data = Buffalodata::find($buffalidforavgmilk);
$data->avgmilk = ($getavg);
$data->save ();
// dump([$milkperid,$avgbuffalocount,$getavg,$data,$id]);
}
return view ('pages.Buffalo.BuffaloDetails',[---------]);
}
Thanks again in Advance
When you pass an Array to ::find(), it returns a Collection, which doesn't have a save() method. This is your code:
// This is an Array of `buffaloID` values
$buffalidforavgmilk = Buffalodata::groupBy('buffaloID')->get('buffaloID')->pluck('buffaloID')->toArray();
...
// `$data` is now a `Collection` of `Buffalodata` instances
$data = Buffalodata::find($buffalidforavgmilk);
// This now fails, as `Collection` doesn't have a `save()` method
$data->save();
You can rewrite your code as follows:
Buffalodata::whereIn('buffaloID', $buffalidforavgmilk)->update(['avgmilk' => $getavg]);
This will update all records in a single call. If you want to iterate, that's an option too:
$data = Buffalodata::find($buffalidforavgmilk);
foreach ($data as $record) {
$record->avgmilk = $getavg;
$record->save();
}
Or, since you have $id already:
$record = Buffalodata::find($id);
$record->avgmilk = $getavg;
$record->save();

How to save data on different database tables in Laravel Backpack

how to save the data from the Features fields on a different table. Example in the link below, it is saving the Features table fields in a JSON field in the database. However, I want to save this data from the features into another table.
https://demo.backpackforelavel.com/admin/product/211/Edit
I'm coming back here to post my answer. I managed to settle, I'm putting here to help other developers.
This first part of the question I have already solved. But now I can not bring the data from the Features fields in the form.
Below is the source code that I was able to save and edit the form data. However, I can not carry the data from the Feature fields. Someone knows how I can carry the field data in Feature
class ProductCrudController extends CrudController
{
use ListOperation;
use CreateOperation {
store as traitStore;
}
use UpdateOperation {
update as traitUpdate;
}
use DeleteOperation;
public function store()
{
// insert item in the db
$item = $this->crud->create($this->crud->getRequest()->except(['save_action', '_token', '_method']));
$features = json_decode($this->crud->getRequest()->input('features'));
foreach ($features as $itens) {
$obj = new Feature();
$obj->product_id = $item->getKey();
$obj->name = $itens->name;
$obj->save();
}
// show a success message
\Alert::success(trans('backpack::crud.insert_success'))->flash();
return redirect('admin/product');
}
public function update()
{
$featureForm = json_decode($this->crud->getRequest()->input('features'));
// insert item in the db
$item = $this->crud->update($this->crud->getRequest()->id, $this->crud->getRequest()->except(['save_action', '_token', '_method', 'features']));
$objF = Feature::where('product_id', $item->getKey())->get();
foreach ($objF as $itens) {
Feature::where('id', $itens->id)->delete();
}
foreach ($featureForm as $itens) {
$obj = new Feature;
$obj->product_id = $item->getKey();
$obj->name = $itens->name;
$obj->save();
}
// show a success message
\Alert::success(trans('backpack::crud.insert_success'))->flash();
return redirect('admin/product');
}
}
I'm coming back here to post my answer. I managed to settle, I'm putting here to help other developers.
I was able to bring the data in the form edition, in the Features fields. I used the Mutators in the Model - https://laravel.com/docs/8.x/eloquent-mutators
Below is the example I did.
It would be interesting to have an example of this in the official documentation or demo project. I believe it would help a lot also to other developers.
//model Product
public function getFeaturesAttribute($value)
{
$objects = Features::where('product_id', $this->id)->get();
$array = [];
foreach ($objects as $itens) {
$obj = new stdClass;
$obj->name = $itens->name;
$array[] = $obj;
}
return \json_encode($array);
}
There are a few ways to go about it. Personally I prefer to create accessors and mutators in the model - https://laravel.com/docs/8.x/eloquent-mutators . Not only does it keep the CrudController clean (so updateable) but it also allows you to save/load stuff from other forms (ex: user-facing forms).
//model Product
public function getFeaturesAttribute($value)
{
$objects = Features::where('product_id', $this->id)->get();
$array = [];
foreach ($objects as $itens) {
$obj = new stdClass;
$obj->name = $itens->name;
$array[] = $obj;
}
return json_encode($array);
}

Can't update a certain field Laravel Elequent

In the controller update method, I can update this field with no problem:
public function updateLecture($id){
$subject = Subject::findOrFail($id);
$subject->name = request('name');
$subject->save();
}
But when I do try to update the description:
$subjet->description = request('description');
It gives me this error :
'Creating default object from empty value'
and I know for certain that the request('description') is not empty.
You did spelling mistake,
$subject->description = request('description'); // make subjet to subject

Can't save UUID field in PHP script iteration, Laravel, Postgres

I'm trying to fill already existing models with UUID. And every time it says that UUID is not unique! What a bloody hell! )))
function unique_guid($model){
$guid = com_create_guid();
$table = $model->table;
$db_table = Db::table($table);
$req = $db_table->where("guid", strval($guid));
$instance = $req->first();
if(is_object($instance)){
$guid = unique_guid($model);
return;
}else{
try{
$model->guid = $guid;
$model->save();
sleep(2);
return $guid;
}catch(PDOException $Exception){
$guid = unique_guid($model);
}
}
}
It keeps circling in try/catch block and telling me that it is not unique,
i checked and there is no record with generated UUID.
Also - it brokes at third-fourth iteration, and if i add sleep(5) it works longer - 10 iteration and then brokes.
What in the world can it be?
Laravel 5.5, Postgres 9
Following the Laravel 6.0 official doc, I proceeded the following way:
I added the uuid-ossp extension at database creation. Then, my migrations were like:
use Illuminate\Database\Query\Expression;
...
public function up()
{
Schema::create('my_table', function (Blueprint $table) {
$table->uuid('guid')->primary()->default(new Expression('uuid_generate_v4()'));
...
});
}
I find it a lot more elegant like this.
I believe com_create_guid is not generating unique on every iteration, so please use some increment/prefix value to generated UUID, also if possible use uniqid instead of com_create_guid() uniqid generates id based on the current time in microseconds.
function unique_guid($model,$increment=0){
$guid = uniqid($increment,TRUE);
$table = $model->table;
$db_table = Db::table($table);
$req = $db_table->where("guid", strval($guid));
$instance = $req->first();
if(is_object($instance)){
$guid = unique_guid($model,++$increment);
return;
}else{
try{
$model->guid = $guid;
$model->save();
sleep(2);
return $guid;
}catch(PDOException $Exception){
$guid = unique_guid($model,++$increment);
}
}
}
I think you created function to generate UUID but there is some other better ways to generate UUID. You are using Laravel so you can search packages which are generating UUID.
There is a package I'm suggesting to use.
https://github.com/ramsey/uuid
These types of packages are useful and fully tested by community. So we can trust on them.
You can try like this.. it will check until the guid is really unique
public static function generateUniqueNumber($model = null, $column = null)
{
$num = null;
if ($model) {
$range = $model::all()->pluck('guid')->toArray();
while (in_array($num = com_create_guid(), $range)) {}
}
return $num;
}
I think it's some bug in Postgres 9.3. It inserting two rows at a time on some point of the script. I've eneded with just a migration like that
public function up()
{
DB::statement('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";');
DB::statement('ALTER TABLE feegleweb_octoshop_products ADD COLUMN guid uuid DEFAULT uuid_generate_v4() UNIQUE;');
}
It fill all my rows with unique uuid

How to get value of logged in user id in controller in laravel?

Top of my controller i have added:
use Auth;
function in my controller
public function details($id)
{
if(Auth::check())
{
$user = Auth::user();
$product = Product::find($id);
$cart->product_id = $product->id;
$cart->category_id = $product->category_id;
$cart->user_id = $user->id;
dd($cart->user_id); //check if its storing the value
}
else {
return redirect()->route('login');
}
}
when I run this i get error:
Creating default object from empty value
If I remove the $user->id line the error goes.
I tried adding constructor also but still got same error
public function __construct() {
$this->middleware('auth');
}
dd is showing other details after it checks if user is logged in.
Is there a way to get user id of logged in user from users table that is created by default.
Thanks!
The issue is you’re calling $cart->product_id, but the $cart variable isn’t defined as far as I can see. PHP doesn’t know what to do, so because you try and assign a property to it, PHP assumes you want $cart to be a class, hence the “Creating default object from empty value” message.
Other than that, you code could be improved by using middleware to authenticate your users, and relations on your Eloquent models so you’re not manually assigning relation IDs.
Try like this,
You forgot to initials cart object
$cart = new Cart;
$cart->product_id = $product->id;
$cart->category_id = $product->category_id;
$cart->user_id = $user->id;
dd($cart->user_id); //check if its storing the value

Resources