Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Eloquent Versioning Laravel Package

proai/eloquent-versioning

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require proai/eloquent-versioning:~1.0
    

    Publish the migration and config (if needed):

    php artisan vendor:publish --provider="ProAI\EloquentVersioning\EloquentVersioningServiceProvider"
    
  2. Run Migrations:

    php artisan migrate
    
  3. Configure Model: Extend your Eloquent model with ProAI\EloquentVersioning\Versionable trait and define versioned attributes:

    use ProAI\EloquentVersioning\Versionable;
    
    class User extends Model
    {
        use Versionable;
    
        protected $versioned = ['email', 'city'];
        protected $versionedTimestamps = true;
        protected $versionedSoftDeletes = true;
    }
    
  4. First Use Case: Create a user and update a versioned attribute:

    $user = User::create(['name' => 'John', 'email' => 'john@example.com', 'city' => 'NY']);
    $user->update(['city' => 'LA']); // Triggers version creation
    

Implementation Patterns

Core Workflows

  1. Versioned Attribute Updates: Automatically creates a new version record in versions table when updating versioned fields:

    $user->email = 'new@example.com'; // Versioned
    $user->save(); // Creates version record
    
  2. Querying Versions: Retrieve all versions for a model:

    $versions = $user->versions()->get();
    

    Get a specific version:

    $version = $user->versions()->where('version', 2)->first();
    
  3. Restoring Versions: Revert to a previous version:

    $user->restoreVersion(1); // Restores version 1
    

Integration Tips

  • Soft Deletes: Enable versionedSoftDeletes to track deletion timestamps in versions.

  • Timestamps: Enable versionedTimestamps to include created_at/updated_at in versions.

  • Custom Version Table: Override getVersionTable() in your model for custom naming:

    protected function getVersionTable()
    {
        return 'user_versions';
    }
    
  • Mass Assignment: Use update() or fill() with versioned fields—versions are auto-created:

    $user->update(['email' => 'updated@example.com', 'city' => 'SF']);
    
  • Events: Listen for versioning.created events to hook into version creation logic:

    Event::listen('versioning.created', function ($model, $version) {
        // Custom logic after version creation
    });
    

Gotchas and Tips

Pitfalls

  1. Performance:

    • Versioning adds overhead to updates. Avoid versioning frequently updated fields on high-traffic models.
    • Querying versions can be slow for large datasets. Use limit() or where() to constrain results:
      $user->versions()->where('version', '<', 5)->get();
      
  2. Migration Conflicts:

    • Ensure your versions table migration matches the package’s schema (e.g., version, model_type, model_id, changes columns).
    • If customizing, manually add missing columns (e.g., deleted_at for soft deletes).
  3. Soft Deletes:

    • Disabling soft deletes ($versionedSoftDeletes = false) removes deleted_at from versioned fields. Ensure this aligns with your model’s softDeletes setting.
  4. Serialization:

    • Complex data (e.g., arrays, objects) in versioned fields may not serialize correctly. Use json columns or cast attributes:
      protected $casts = ['metadata' => 'array'];
      

Debugging

  • Missing Versions: Check if the model uses the Versionable trait and $versioned attributes are correctly defined. Verify the versions table exists and has the right schema.

  • Silent Failures: Enable Laravel’s query logging to debug version creation:

    DB::enableQueryLog();
    $user->update(['email' => 'test@example.com']);
    dd(DB::getQueryLog());
    
  • Version Overwrites: If versions aren’t updating, ensure save() or update() is called (not direct attribute assignment without persistence).

Extension Points

  1. Custom Version Data: Override getVersionData() to include additional fields in versions:

    protected function getVersionData()
    {
        return array_merge(parent::getVersionData(), ['custom_field' => $this->custom_field]);
    }
    
  2. Version Comparison: Add helper methods to compare versions:

    public function diffVersions($version1, $version2)
    {
        $v1 = $this->versions()->where('version', $version1)->first();
        $v2 = $this->versions()->where('version', $version2)->first();
        return json_decode($v1->changes, true) - json_decode($v2->changes, true);
    }
    
  3. Version Filtering: Extend the versions() scope for custom queries:

    public function scopeActiveVersions($query)
    {
        return $query->whereNull('deleted_at');
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky