yajra / laravel-datatables-editor

Laravel DataTables Editor Integration.
https://yajrabox.com/docs/laravel-datatables/editor-installation
MIT License
115 stars 14 forks source link

Eloquent model should refresh after saved #43

Closed bitrevo closed 5 months ago

bitrevo commented 4 years ago

I am using $with attribute in my Eloquent model and using this datatables editor library. I found that every time I updated a select field in my datatables, it display the old value instead of updated value.

This issue should be caused by Laravel save() method, it wont refresh the relationships automatically. We need to manually refresh it.

$model = $model->fresh();

https://github.com/yajra/laravel-datatables-editor/blob/2e09ebe5d422d07d6a766ffa426ac64c3fba70ee/src/DataTablesEditor.php#L328

For temporary fix, refresh it manually in updated event.

public function updated(Model $model, array $data)
{
    $model = $model->fresh();
    return $model;
}
improved-software commented 4 years ago

This is expected behaviour and the purpose of the updated event.

Adding in a refresh using the fresh() method will cause an extra query every time something is updated. So should only be added when this is necessary.

If there are multiple relationships, I personally use a function with a single query to get what I need then add those as attributes to the model. This will update the select fields (but only uses 1 extra query).

public function updated(Model $model, array $data) {

    $details = $this->getBlockVarietyDetails($model);

    $model->setAttribute('block_name', $details[0]->block_name);
    $model->setAttribute('variety_name', $details[0]->variety_name);
    $model->setAttribute('season_name', $details[0]->season_name);
    return $model;
}
private function getBlockVarietyDetails(FarmBlockVariety $model) {

    $id = $model->id;
    return FarmBlockVariety::query()
        ->select(
            'farm_blocks.name AS block_name',
            'farm_varieties.name AS variety_name',
            'setting_seasons.short_name AS season_name'
        )
        ->join('farm_blocks', 'farm_block_varieties.block_id', '=', 'farm_blocks.id')
        ->join('farm_varieties', 'farm_block_varieties.variety_id', '=', 'farm_varieties.id')
        ->join('setting_seasons', 'farm_block_varieties.season_id', '=', 'setting_seasons.id')
        ->where('farm_block_varieties.id', '=', $id)
        ->get();
}

So if you are using $with in your model what you have done is correct. In the updated method you need to specify if you need anything other than the database record itself returned.

github-actions[bot] commented 5 months ago

This issue is stale because it has been open for 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] commented 5 months ago

This issue was closed because it has been inactive for 7 days since being marked as stale.