I found that the soft-delete in laravel Eloquent ORM is just replacing the null in deleted_at column by a timestamp. When querying a table with soft delete, is it just checking if the deleted_at is null, or it is really comparing the value with current time?
I am asking to see if I am able to do schedule delete by setting a future time on the deleted_at column.
Laravel only checks if deleted_at is not NULL. SoftDeletingScope:
public function apply(Builder $builder)
{
$model = $builder->getModel();
$builder->whereNull($model->getQualifiedDeletedAtColumn());
$this->extend($builder);
}
You can change that by creating your own SoftDeletingScope and SoftDeletingTrait (it's called SoftDeletes in Laravel 5).
trait MySoftDeletingTrait {
use Illuminate\Database\Eloquent\SoftDeletingTrait;
public static function bootSoftDeletingTrait()
{
static::addGlobalScope(new MySoftDeletingScope);
}
}
And
class MySoftDeletingScope extends Illuminate\Database\Eloquent\SoftDeletingScope {
public function apply(Builder $builder)
{
$model = $builder->getModel();
$builder->where($model->getQualifiedDeletedAtColumn(), '<=', Carbon::now());
$this->extend($builder);
}
}
Note that to be able to remove the scope (the remove() method) you would have to override more of the original scope class. At least also isSoftDeleteConstraint, but I'll leave that to you.
Finally you only have to switch out the trait that you use in your models:
use MySoftDeletingTrait;
Related
$inst = Institution::find($institution->id);
$campus = InstitutionCampusId::where('institution_campus_id.institution_id' , $institution->id);
$inst->delete();
$campus->delete();
Cascading deletes are handled at the database-level, so when you set onDelete('cascade') in your migration, that translates to your database deleting any records attached by foreign key.
Soft deletes are handled by the application, so you'd either need to fire an event on the parent model and listen for it on the children or, in your parent model, bind the static::deleted() method in the boot method, and delete the relationships there.
I'm not sure if you could do something like:
public static function boot()
{
parent::boot();
static::deleted(function ($model) {
// Probably lazy load these relationships to avoid lots of queries?
$model->load([ 'relationshipOne', 'relationshipTwo', ]);
$model->relationshipOne()->delete();
$model->relationshipTwo()->delete();
});
}
Or if you'd have to iterate over the related items:
public static function boot()
{
parent::boot();
static::deleted(function ($model) {
$model->relationshipOne->each(function ($item) {
$item->delete();
});
$model->relationshipTwo->each(function ($item) {
$item->delete();
});
});
}
Add trait to your model use SoftDeletes; and on your migration add $table->softDeletes() on the end of the schema creation (this be automatically create deleted_at column)
And for query you can use eloquent methods to get only deleted or without deleted entries, example:
To get only deleted entries: $query->onlyTrashed(),
To get only non deleted entries: $query->withoutTrashed(),
To get all entries (with deleted): $query->withTrashed()
To send entry in trash use: $model->delete(),
For permanently delete entry use: $model->forceDelete()
add this trait in your model
use SoftDeletes;
add this in your migration it will add deleted at field in your table
$table->softDeletes();
I have a list of record.
Its model has this
protected static function booted()
{
static::addGlobalScope(new OrderByDescriptionScope);
}
this scope is doing
public function apply(Builder $builder, Model $model)
{
$builder->orderBy('descrizione', 'asc');
}
but when opening a list, records are never sorted by descrizione.
This is the suggested method of apply a global scope, as for laravel 8 documentation.
Why does my code not work?
How to set default sorting for laravel backpack?
using crud object, you can sort your recodes using orderBy method, for example:
public function setupListOperation()
{
$this->crud->orderBy('created_at', 'desc');
}
$collect_all = $collect_all->sortByDesc("id");
$collect_all->values()->all();
when you fetch data after order like this.
JoinSkipReason has not id, but JoinReview's primary key is foreign key of JoinSkipReason.
Query Builder works well...
I want to use with() to join the JoinSkipReason to the JoinReview table.
Thank you.
JoinReview::with(
'join_skip_reason'
);
class JoinReview extends Model
{
public function joinSkipReason()
{
return $this->hasOne('App\Models\Service\JoinSkipReason');
}
}
class JoinSkipReason extends Model
{
protected $fillable = ['join_review_id', 'reason'];
public function joinReview()
{
return $this->belongsTo('App\Models\Service\JoinReview', 'id');
}
}
I've encountered this issue myself, the issue is that for eager loading multi-word relations you should use camelCase.
In your code:
JoinReview::with(
'joinSkipReason'
);
I've also found a (kinda old) issue saying that you should also access the eager-loaded relation as camelCase, otherwise it will ignore the cached result and query the database again.
Check do like that
public function joinSkipReason()
{
return $this->hasOne('App\Models\Service\JoinSkipReason','join_review_id','id');
}
I have records of a Model that I need to delete, however I need to delete their id's also from the pivot table, so I tried to listed to deleted event, but it didn't work
Here is how I add the event:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Criteria extends Model {
protected $table = 'criterias';
public static function boot()
{
parent::boot();
static::deleted(function($criteria)
{
DB::table('criteria_criteria')->where('criteria_id', '=', $criteria->id)->delete();
});
}
}
I am on Laravel 5.1, any idea how to do so?
I think you have not used its relationship. Please create a relationship with your pivot table like this.
public function criteria()
{
return $this->belongsToMany('App\Criteria');
}
This will automatically manage your deletion query on pivot table. It has also one benifit you can use its sync and detach methods to add and remove pivot table records.
For more detail you can read in this tutorial by search keyword pivot.
I just started to work on a project with a clean laravel 4.2 installation (from 5 days ago).
I have a model defined like this:
<?php
use Illuminate\Database\Eloquent\SoftDeletingTrait;
class Code extends Eloquent {
use SoftDeletingTrait;
protected $dates = ['deleted_at'];
public function group() {
return $this->belongsTo('Group');
}
public function user() {
return $this->belongsTo('User');
}
}
The table is created with $table->softDeletes();, and has a nullable deleted_at column.
Now when I delete a record with Code::find(1)->delete(); the deleted_at column is filled with current date.
But then when I do Code::all(), or Code::find(1), the result includes soft deleted records, but I expected it not to include them unless I specifically want deleted results...
I've already read http://laravel.com/docs/4.2/upgrade#upgrade-4.2 and my model reflects what is written there.
Am I missing something, or is this a bug in 4.2?