How to undo database after update in laravel? - laravel

I have two buttons, updates and undo. For example, after I update the new database, I want to undo it back to the original. I can only execute the update button.
function update(Request $req)
{
$id = $req->contact_id;
$contract = Contacts::find($id);
$contract->area_id = $req->areas;
$contract->code = $req->code;
$contract->created_at = $req->sign_in;
$contract->value = $req->total;
$contract->save();
return redirect('contact/'.$id)->with('message', 'Update successful !!');
}

To do that you must keep somewhere your old record before you update.
There is no "undo" so don't think it like that. You basically want to update the table with the old values.
Since as you said you have 2 buttons which one of them is the update which updates the current record what you can do, to make undo possible is that you have another table like records which you are going to fill in every update.
So according to your code the field contact_id seems like the unique identifier for each contract. Before you update then with the new values you can use a select like:
$oldRecord = DB::table('my_main_table')
->where('id', $req->contact_id)->first();
Inside your $oldRecord variable is stored all the info of your record that you want to update but is not yet updated , so it's your old record. Having that you can just hit an insert query to the records table i mentioned before so you can keep your "older version" there in case you want to undo.
So the undo functionality will just be the same logic. Select the record with the specific contract_id but this time from the records table and just update your main table.

I don't know if I fully got your question, but as long as you haven't called the save() method on your model, you can use
$eloquentModel->getChanges()
to list all attributes you did already change.
You can retrieve original attribute values by calling
$eloquentModel->getOriginal();

Related

Spatie Laravel ActivityLog use with differences on update and on create

I have a call to getActivitylogOptions() in a model.
But I need the data saved in the log to be different in the case of insert/update/delete.
For example, when inserting a new line, I only want to save one or two info fields. But in case of an update, I need to save all the fields that have been modified to know what exactly the user modified.
If I leave it like the following code, the update is correct, but when inserting, it saves all the fields which I don't need.
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logAll()
->logOnlyDirty();
}
Is there any way to change the log according to the action?

How to rollback a specific row in JDeveloper ADF?

is there a way to rollback a specific change. I have a button that creates a row in two different tables. I want the changes in one of the tables to be rolled back before the committing so that only the second table is committed. How would this be done? Running normal rollback rollbacks both table iterators.
Ive been trying different methods and nothing is working, Please help before I go insane.
find out the corresponding 'VO' row which you want to rollback .
#1. row.setNewRowState(Row.STATUS_INITIALIZED) ;
or
#2. row.revertRow() ;
or
#3. row.remove() ;
The closest thing to rolling back a row would probably be calling refresh on the view row with the appropriate parameters, something like this:
//Obtain app module
DCBindingContainer dcb = (DCBindingContainer) BindingContext.getCurrent().getBindingsEntry();
ApplicationModuleImpl am = (ApplicationModuleImpl) dcb.getDataControl().getDataProvider();
//Get your view
ViewObjectImpl vo = am.getMyView1;
ViewRowImpl row = vo.getCurrentRow(); //alternately use vo.findByKey to lookup a row or simply iterate through every row if dataset is sufficiently small
//rollback the row
row.refresh(Row.REFRESH_REMOVE_NEW_ROWS | Row.REFRESH_UNDO_CHANGES | Row.REFRESH_CONTAINEES);//review modes for ideal combination for use case
Note that rather than a refresh, a row.remove() would probably be sufficient for what it sounds like you are trying to do. In any case, you will need to keep track of the rows you do not want to commit.
While this solution would work, it does not sound ideal for your use case. If you never commit data in the other table, there is no reason to link it to a database table. I would probably do something like one of the following instead:
If the fields are the same in both tables (or similar) and it will be an all-at-once action, create a transient attribute on the ADF view object to denote whether or not the row is approved. Use view criteria on different instances of the view object (add to your application module twice) to display/process the rows you want. Remove not approved rows prior to committing.
If the fields needed are too different or you want to be able to handle one row at a time, make you history view object a programmatic view object with transient attributes, rather than basing it on the table/Entity. When a row is approved remove it from your history view and add it to your approved view.

How to display in blade which rows are soft deleted?

I have created a polling system and in the backend (CMS area) I want the ability for admins to be able to remove polls. When an admin removes a poll, it should soft delete the poll. This is working as intended, however I also want to have the ability for the admin to be able to restore a poll. To do this I am displaying all of the polls (including the soft deleted polls) in the admin area.
PollController index() to get all polls
$polls = Poll::withTrashed()->get();
In the blade I want to have two different buttons for each poll. One of restoring and one for deleting but I only want to display 1 button for each poll depending on whether it can be restored or deleted.
To do this, I have put this inside the foreach in the blade:
#if($poll->trashed())
// Restore button
#else
// Delete button
#endif
However the issue is, trashed() keeps returning true for all the polls when only 1 out of the 3 polls I have are actually soft deleted. I am unsure as to why trashed() returns all of these are true?
How would I get this method working correctly? Thanks.
PART 1
It depends on your query. When using soft deletes, Laravel will query all models that are not soft-deleted by default. When you also want to get the soft-deleted models, you need to call the withTrashed() method on your query. Read more here:
https://laravel.com/docs/5.5/eloquent#querying-soft-deleted-models
To understand what withTrashed() does, you need to understand how soft-deleting works. Soft-deleting models works by adding a new column to your database tables called deleted_at. It's value defaults to null. When you soft-delete a model, Laravel will put the current timestamp into that column. Therefore, this field doesn't contain a null value anymore.
When querying models when using soft-deletes, Laravel appends a deleted_at is null condition to the query. Calling the withTrashed() method, removes that condition from the query.
Have a look on the source of the default query modifier and the withTrashed method.
PART 2
That are events. You can call that to tell Laravel, that it should execute that specific closure when this event happens. In your example, it is listening for the "deleting" event. See more on that here:
https://laravel.com/docs/5.5/eloquent#events
PART 3
You can entirely delete soft-deletable models with the forceDelete() method. See "Permanently Deleting Models" here:
https://laravel.com/docs/5.5/eloquent#querying-soft-deleted-models
FOR EXAMPLE
$items = App\Model::withTrashed()->get();
If you want to restore a single item, just find it by ID:
$item = App\Model::find($id);

Why Laravel/Eloquent single object save() updates multiple records

I'm fetching a specific record with a DB table using
$myTableObj = MyTable::where(['type' => $sometype])->first();
Getting it successfully, updating some fields and saving with
$myTableObj->save();
Surprisingly, this record is updated along with another record that also has 'type' = $sometype. What can be done to prevent this?
NOTE: originally the table did not have the auto increment id field, but I have read in forums that it may make problems in Laravel so I did add it, which did not solve the problem.
Method save() working with 'id' filed only.
You can try this
$myTableObj = MyTable::where(['type' => $sometype])->update(['something' => 'value']);
Source
I understand update() is to update, but, my answer works fine and fits good for update too. Its useful where you dont want columns to be defined once again for update, (sp when they are not fillable, its tested with primary key as condition)
$myTableObj->save(); basically its for saving new record, if you want to update that row you can update like below code:
$myTableObj=new MyTable;
$myTableObj->exists=true;
$myTableObj->type=$sometype;//this is your condition, identify
$myTableObj->update();
I think what's happening here is Laravel is saving as well as updating row.

Use new inserted id for another field in sugarcrm

I want to use new inserted id for another field after insert.
I want to use it for my document ID, example when new record inserted, the auto increase id will have a prefix and follow with the auto increase id, it will stored in the account custom table (account_cstm) with a new field call "document_id_c".
Example the auto increase id is 18, the data will be stored in document_id_c is "DOC18".
I tried smtg in logic hook:
$bean->account_number_c = 'DOC'.$bean->account_number;
$bean->save();
But it seems like not working.
Another problem is, i need to show immediately after record has been saved.
Need some advice.
Thanks!!
First use $bean->id = create_guid(); after that create custom id accordingly and assigned in your field and call $bean->save();

Resources