Skip to content

after_save hook does not provide the old ActiveModel state (breaks update workflows such as file replacement) #2814

@usamassem

Description

@usamassem

Problem Summary

In ActiveModelBehavior, the after_save hook receives only the newly saved Model.
There is no way to access the old values that the record had before the update.

This makes it impossible to implement correct update-related logic inside the ORM hook system—especially workflows where an update corresponds to a delete + insert in external systems (filesystem, caches, search indices, object stores, etc).


Why this is a real limitation

When updating something like an uploaded file, the flow is:

  • Old file path: old_path
  • New file path: new_path

The correct logic is:

  1. Save new file
  2. Update DB
  3. After update succeeds → remove old file from disk

But after_save receives only the new model, so the old_path is lost.

Logging, auditing, caching, search-index re-sync, messaging, and any "diff-style" operations cannot be done inside SeaORM because the previous values are unavailable.


Current behavior

  • before_save(self: ActiveModel) gives old values but file hasn’t been written yet & update hasn’t succeeded
  • after_save(model: Model) gives new values only old values lost
  • Adding ignored fields to ActiveModel does not work with seaography and other tools
  • SeaORM currently cannot express: "run this logic after a successful update, and also give me the old values"

What is expected / requested

It would be extremely helpful if SeaORM provided one of the following:

Option A: Pass both the old and the new model to after_save

async fn after_save<C>(
    old: Model,
    new: Model,
    db: &C,
    insert: bool
) -> Result<Model, DbErr>

Option B: Pass the old ActiveModel into after_save

async fn after_save<C>(
    old: Model,
    new: Model,
    db: &C,
    insert: bool
)

Option C: Add a new hook:

after_update(old_model, updated_model)
Separate from insert.

Option D: Provide an official "diff" mechanism

Expose the previous snapshot before update.


Why this matters

Many real-world systems require old-value access on update:

  • File uploads (delete old file after update)
  • Image processing (regenerate thumbnails)
  • Object storage cleanup
  • Search index re-sync
  • Cache invalidation
  • Logging changes
  • Webhooks or events describing what changed
  • Soft-delete recovery logs
  • Auditing systems

Without old value access, developers must move this logic outside the ORM (e.g., into resolvers or services), which defeats the purpose of having hooks.


Conclusion

This missing piece makes after_save far less useful than it could be, and forces non-atomic, non-transactional logic at higher layers of the application.

A mechanism to access the old state on update would significantly improve SeaORM for real application workflows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions