How to check id which I used from a table that related with other multiple table? - laravel

When I want to delete a row from table I want to check the tables which use the id of this row. If used then it doesn't allow to delete.

You can simply check whether specific column(containing other table's key) in the row is empty or null and if it is empty then delete the row otherwise skip it.
You have two ways in which you can do it-
using eloquent get the row by primary key and check the property on collection.
write a stored procedure in the database and call it in your Laravel code.

You can use the deleting model event to check if the relationships exist. If they do, then prevent the delete.
https://laravel.com/docs/5.7/eloquent#events
If you create an observer for your model, you can use something like this:
public function deleting($model)
{
if($model->someRelation->count()) { // replace ->someRelation with whatever you want to check
return false; // prevent delete
}
if($model->anotherRelation->count()) {
return false; // prevent delete
}
}

Related

Get record real value after overriding it

I've overridden a a record value like the following :
public function getWeightAttribute($weight)
{
if($weight)
{
return $weight;
}
return 70;
}
Now I have a collection of that model and I want to know if the original value was null or not.
I want to do it without connecting to DB again, Actually I want to make sure the user has filled the weight and some other fields while registering.
Some sections are working based on the above override and I don't want to mess them up neither use extra connections to db.
Thanks In Advance,
In order to get the original value, you can use:-
$fetchData->getAttributes()['weight'];

how to restore soft delete with one more column?

I have a table named data and I am using soft delete to delete the record.i have one more field in my data table which is also updated when a record is deleted. but when I restore that soft deleted record, it updates my deleted_at field but doesn't update the other field.
I use this code
Data::withTrashed()->find($id)->restore();
How can I do this?
You could write an observer that hooks into the restored event:
<?php
namespace App\Observers;
class DataObserver
{
public function restored($data)
{
// Update field here
}
}
And of course register it a boot() method of a service provider:
Data::observe(DataObserver::class);
Note: Depending on the timing, you may prefer the restoring event instead
Data::withTrashed()->find($id)->restore();
meant this only for restoring which is set the deleted_at column to null
so if you want update the other field, just do the usual things for updating fields after you restore it
like this one
Data::withTrashed()->find($id)->restore();
Data::find($id)->update($array);
To achieve this you can create function in your Data model which will do that for you.
public function restoreItem()
{
$this->deleted_at = null;
$this->other_field = null;
$this->save();
}
Now you need to call this in your controller:-
Data::withTrashed()->find($id)->restoreItem();
That's it.
This will work
Data::withTrashed()->whereId($id)->update([
'deleted_at'=>null,
'other_column'=>$value,
]);

Laravel Auditing - How To Get Specific Column Using Eloquent Model Method

I'm using Laravel Auditing Package to trace changes on my models.
I want to get a specific column of the foreign key in it's primary table before recording the events (create, update, delete) in the audit table.
There is a way the package helps get all the attribute of the foreign key, it's called Audit Transformation but it generates an error for me when displaying the details in the table i want to know if there's any eloquent model method to get the specific column info i need instead of using getattribute() method which gets the entire row of the item_id.
Audit Transformation Method
public function transformAudit(array $data): array
{
if (Arr::has($data, 'new_values.item_id')) {
$data['old_values']['item_name'] = Item::find($this->getOriginal('item_id'));
$data['new_values']['item_name'] = Item::find($this->getAttribute('item_id'));
}
return $data;
}
This is how it's stores in the database ephasis on the item_name.
{"item_id":"1","qty_received":"2","delivered_by":"John",
"received_by":"Abi","supplier":"Stores","date":"2019-11-26","item_name":{"item_id":1,"item_name":"Toner","colour":"Black","status":"Active",
"created_at":"2018-10-25 17:55:26","updated_at":"2018-10-25 17:55:26"}}
And this is the Item table schema
So in my scenario i'd want to store the item_name as Toner not the entire row of the item_id
Any suggestion will be welcomed, thanks in advance.
Add ->item_name->item_name after the function of Find.
if (Arr::has($data, 'new_values.item_id')) {
$data['old_values']['item_name'] = Item::find($this->getOriginal('item_id'))->item_name->item_name;
$data['new_values']['item_name'] = Item::find($this->getAttribute('item_id'))->item_name->item_name;
}

Questions related to soft delete in laravel

I have some questions relating to soft delete in laravel. I have search up on what it does and what it means and the most understandable part about soft delete is from this sentence
"When models are soft deleted, they are not actually removed from your
database. Instead, a deleted_at attribute is set on the model and
inserted into the database. If a model has a non-null deleted_at
value, the model has been soft deleted. To enable soft deletes for a
model, use the Illuminate\Database\Eloquent\SoftDeletes trait on the
model and add the deleted_at column to your $dates property:"
So here are my questions based from that sentence:
Q1:
So when I use soft delete in my code, and when I try to delete some
data, does the data in the view page(blade.php) disappear while the
database still contain those data?
Q2:
I saw some people using something called static::deleting, I don't
really quite get how this work? Could you explain what it does? Thank
you
Q3:
How do you delete data using soft delete? I saw people just putting
some stuff into their model instead of using button, so does that mean
you can only delete it manually inside the model instead of just
clicking the delete button in the view page?
Question 1
By default: Yes.
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.
Question 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
Question 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
Q1: So when I use soft delete in my code, and when I try to delete
some data, does the data in the view page(blade.php) disappear while
the database still contain those data?
Yes. The soft delete fill the deleted_at column in the database. Since that, Eloquent will not retrieve these data (except if you ask for). If you use custom SQL request, you'll need to add a WHERE deleted_at IS NULL
Q2: I saw some people using something called static::deleting, I don't
really quite get how this work? Could you explain what it does? Thank
you
I'm not using that day to day, but it's an event you can call (see here ) to automatically delete content related (for example, if you remove an user, you can also remove all his post. It's kind of cascading delete)
Q3: How do you delete data using soft delete? I saw people just
putting some stuff into their model instead of using button, so does
that mean you can only delete it manually inside the model instead of
just clicking the delete button in the view page?
To use the soft delete, you just $object->detroy($id) or $myEloquentRequest->where(...)->delete()
If you want to force a real delete (so the entries will be definitly removed from the database), you can use $flight->forceDelete();
See here for more.
You can do the delete wherever you want. The click on a button bring the user to the delete() method in your controller. You can delete there or call a method inside the model to trigger the delete (and maybe some more complex deleting like event ... )
Soft delete means not delete records in database.So we handle one flag
for manage records is deleted or not.
Let's i explain more with examples :
In our records many user so we add one fields delete_at into database and defaults it's value null so it's records is not deleted.
Now when we fetch all user data we write query like
Select * from user where delete_at = null
So this query return all user data which is not deleted.
Now we delete this user so when we click on delete button we create custom query and update this user delete_at fields with current datetime
Update delete_at=date() where user_id = 1
so now this records is soft delete.
Now i answer your question:
Q.1)No data not displaying after soft delete because when we fetch data it's check delete_at fields null or not.
clarifying your points.
1. So when we use soft delete in code, deleted_at will be updated to present timestamp from null, so while querying data from that particular table from anywhere in your project the eloquent model will automatically return data whose deleted_at is set NULL i.e., it is not soft deleted.
people using something called static::deleting.
you might have seen somewhat like this example if I am understanding your question in right way:
class X-Model extends Eloquent
{
public function xy()
{
return $this->has_many('XY_Model');
}
// this is a recommended way to declare event handlers
protected static function boot() {
parent::boot();
static::deleting(function($x) {
// before delete() method call this
$user->xy()->delete();
// do the rest of the cleanup...
});
}
}
This is a use-case for Eloquent events to delete a record which will use the "deleting" event to do the cleanup.
delete data using soft delete
now after calling this, you can soft delete the data from the table and also u can soft delete the data from other dependent tables if relationships are maintained properly in models. this is actually known as cascading effect. example for you to understand.
Model structure:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Utilities\Uuids;
use Illuminate\Database\Eloquent\SoftDeletes;
use Iatstuti\Database\Support\CascadeSoftDeletes;
class XFolder extends Model
{
use SoftDeletes, CascadeSoftDeletes;
use Uuids;
protected $connection = 'XDB';
protected $table = 'x_folder';
protected $dates = ['deleted_at'];
public $incrementing = false;
protected $cascadeDeletes = ['XReference']; //related table with foreign keys
protected $visible = [ 'id', 'x_id', 'xz_id', 'at_id', 'title', 'description', 'description', 'status', 'created_on' , 'is_active'];
protected $fillable = [
'x_id',
'xz_id',
'at_id',
'title',
'description',
'status',
'created_on',
'is_active'
];
public function XReference()
{
return $this->hasMany('App\Models\XReference', 'x_id');
}
}
now in the controller you can call like this:
public function deleteData($id)
{
$results = $this->getModel()->where('id', $id)->deleteData();
return $results;
}
this will delete data (soft delete in cascading format).
Q1: So when I use soft delete in my code, and when I try to delete some data, does the data in the view page(blade.php) disappear while the database still contain those data?
Yes, if your model use softDelete, than the search query will be like this: Select * from table_name where delete_at = null
Q2: I saw some people using something called static::deleting, I don't really quite get how this work? Could you explain what it does?
You can do it with: Modelname::destroy($id) static action
It destroys the model object where the $id is set. On destroying I mean: it updates the deleted_at column, so the aplication will see it as a soft deleted object
Q3: How do you delete data using soft delete? I saw people just putting some stuff into their model instead of using button, so does that mean you can only delete it manually inside the model instead of just clicking the delete button in the view page?
Example of one of my project:
I have a delete button at the partner screen what routes to partner/{{ id }}/delete
at the routes: Route::get('/partner/{id}/delete', 'PartnerController#deletePartner');
What goes to this action:
public function deletePartner($partnerId = 0){
if ($partnerId > 0){
Partner::destroy($partnerId);
}
return redirect("/partner");
}
So: If I click to delete button it check, that the ID is set and then "destroys it" (soft delete). After deletion it redirects back to the partner
EDIT:
For the example given in the question 3, when you delete the data, does the database data disappear or only the view?
It will dissapear only from the view. In the database it will be stored as:
id name ... created_at updated_at deleted_at
1 foo ... 2017-10-01 00:00 2017-10-01 00:00 NULL
2 bar ... 2017-10-01 00:00 2017-10-01 00:00 2017-10-25 16:00
The first one is a non-deleted the second one is a soft-deleted object and the view only will show the first one

ADO.NET DataRow - check for column existence

How do I check for the existence of a column in a datarow?
I'm building datatables to organize some data that I've already pulled back from the database. Depending on the type of data in each row, I need to create a datatable with different columns. Then, later on, I want to check and see if the datatable I am looking at has a certain column.
I know I can catch the exception and handle it that way, but I'm curious if there is a property or method on the datarow object that will do this for me?
Here's how I can do it by catching the exception:
public static String CheckEmptyDataRowItem(DataRow row, String rowName, String nullValue)
{
try
{
return row[rowName].ToString();
}
catch (System.ArgumentException)
{
return nullValue;
}
}
You can simply check like this:
return row.Table.Columns.Contains(columnName);
DataTables have that schema info, so check if the Row's Table's Columns collection contains the field.

Resources