mpociot/versionable

repository·master·Indexed 21 days ago

https://github.com/mpociot/versionable

A Laravel package for tracking changes to Eloquent models and reverting them to previous states. It provides the VersionableTrait to enable versioning, methods to diff attributes between versions, and functionality to restore models to historical states. It supports custom version tables, attribute exclusion via $dontVersionFields, and version limits via $keepOldVersions.

Tokens
2.4K
Snippets
16
Records
17
Agent score
72%

What's inside versionable

  1. Install Versionable via Composer

    master

    Install the package using Composer and then run the migrations to set up the necessary database tables.

    composer require mpociot/versionable
    
    # Run migrations from the vendor directory
    php artisan migrate --path=vendor/mpociot/versionable/src/migrations
  2. Alternatively, publish migrations for customization

    master

    If you want to customize the versioning table structure before running migrations, publish the migration files to your application first.

    php artisan vendor:publish --provider="Mpociot\Versionable\Providers\ServiceProvider" --tag="migrations"
    
    # Then run your standard migrations
    php artisan migrate
  3. Add versions to existing data

    master

    Since Versionable creates versions on update(), existing models won't have a version history by default. You can manually create initial versions for existing records.

    To create a version for a single model instance:

    $model->createInitialVersion();

    To initialize versions for all instances of a specific model class:

    Model::initializeVersions();
  4. Use a custom table for model versions

    master

    By default, all versions are stored in the versions table. To use a dedicated table for a specific model:

    1. Create a custom version model that extends Mpociot\Versionable\Version and set the $table property.
    2. In your main model, use the VersionableTrait and set the $versionClass property to your custom version model class.
    3. Create a migration for the new table.
    // 1. Define custom version model
    class MyModelVersion extends Version
    {
        protected $table = 'mymodel_versions';
    }
    
    // 2. Link it to your main model
    class MyModel extends Model
    {
        use Mpociot\Versionable\VersionableTrait;
        protected $versionClass = MyModelVersion::class;
    }
  5. Enable versioning on a Laravel Model

    master

    To track changes for a specific model, include the Mpociot\Versionable\VersionableTrait in your model class. Once added, every time the model is updated, a new version containing the previous attributes will be stored in the database. Timestamps and soft-delete timestamps are automatically ignored.

    class Content extends Model {
        use Mpociot\Versionable\VersionableTrait;
    }
  6. Exclude attributes from versioning

    master

    To prevent specific attributes (like last_login_at) from triggering a new version every time they change, define the $dontVersionFields array property in your model.

    class User extends Model {
        use Mpociot\Versionable\VersionableTrait;
    
        /**
         * @var array
         */
        protected $dontVersionFields = [ 'last_login_at' ];
    }
  7. Limit the number of stored versions

    master

    To prevent the versions table from growing indefinitely, you can limit the number of versions kept per model by setting the $keepOldVersions property.

    class User extends Model {
        use Mpociot\Versionable\VersionableTrait;
    
        // Keep only the last 10 versions
        protected $keepOldVersions = 10;
    }
  8. Include hidden fields in version data

    master

    By default, fields hidden via Laravel's $hidden property are not included in version data. To ensure these fields are saved in the version history, add them to the $versionedHiddenFields property.

    class User extends Model {
        use Mpociot\Versionable\VersionableTrait;
    
        // Typically hidden fields
        protected $hidden = ['email', 'password'];
    
        // Save these hidden fields in versions
        protected $versionedHiddenFields = ['email', 'password'];
    }
  9. Publish Versionable configuration and migrations

    master

    To customize the package behavior or set up the necessary database schema, you can publish the configuration file and migration files to your Laravel application using the Artisan command.

    Use the --tag flag to specify which assets to publish:

    • config: Publishes the configuration file to config/versionable.php.
    • migrations: Publishes the database migrations to your database/migrations directory.
    # Publish configuration
    php artisan vendor:publish --tag=config
    
    # Publish migrations
    php artisan vendor:publish --tag=migrations
  10. Disable versioning for a request

    master

    If you need to perform updates without creating new version entries (e.g., during a bulk background process), use disableVersioning() and enableVersioning() on the model instance.

    $user = User::find(1);
    $user->disableVersioning();
    
    // This update will NOT create a new version entry.
    $user->update(['some_attribute' => 'changed value']);
  11. Revert to a previous version

    master

    You can restore a model to a previous state using the following methods:

    Revert to the immediate previous version:

    $content->previousVersion()->revert();

    Revert to a specific version ID:

    $revertedModel = Version::find( $version_id )->revert();
    // Restore to the previous change
    $content->previousVersion()->revert();
    
    // Get model from a version
    $oldModel = Version::find(100)->getModel();
  12. Retrieve versions associated to a model

    master

    You can access all versions of a model using the versions attribute. This is a MorphMany relationship, so it can be treated like any other Laravel relationship.

    $versions = $model->versions;