All Projects → westonganger → active_snapshot

westonganger / active_snapshot

Licence: MIT license
Simplified snapshots and restoration for ActiveRecord models and associations with a transparent white-box implementation

Programming Languages

ruby
36898 projects - #4 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to active snapshot

paper trail-association tracking
Plugin for the PaperTrail gem to track and reify associations
Stars: ✭ 103 (+53.73%)
Mutual labels:  activerecord, associations
Paper trail
Track changes to your rails models
Stars: ✭ 6,185 (+9131.34%)
Mutual labels:  activerecord, audit
Logidze
Database changes log for Rails
Stars: ✭ 1,060 (+1482.09%)
Mutual labels:  activerecord, versioning
n1 loader
Loader to solve N+1 issues for good. Highly recommended for GraphQL API.
Stars: ✭ 182 (+171.64%)
Mutual labels:  activerecord
mysql-sp-audit
Using trigger based stored procedure to create audit table. It follows the wordpress meta data approach to store the changes, so all the data is store in just two centalized tables.
Stars: ✭ 27 (-59.7%)
Mutual labels:  audit
version-sync
Keep version numbers in sync with Cargo.toml
Stars: ✭ 65 (-2.99%)
Mutual labels:  versioning
sinatra-bootstrap
My opinionated Sinatra base application
Stars: ✭ 14 (-79.1%)
Mutual labels:  activerecord
Scenic
Scenic is maintained by Derek Prior, Caleb Hearth, and you, our contributors.
Stars: ✭ 2,856 (+4162.69%)
Mutual labels:  activerecord
activerecord-debug errors
An extension of activerecord to display useful debug logs on errors
Stars: ✭ 23 (-65.67%)
Mutual labels:  activerecord
cis benchmarks audit
Simple command line tool to check for compliance against CIS Benchmarks
Stars: ✭ 182 (+171.64%)
Mutual labels:  audit
speckle-blender
speckle.systems/tag/blender/
Stars: ✭ 38 (-43.28%)
Mutual labels:  versioning
minver
What are the minimum dependencies for your package?
Stars: ✭ 18 (-73.13%)
Mutual labels:  versioning
embedded
Rails/Activerecord plugin to make value objects embedded into active record objects
Stars: ✭ 48 (-28.36%)
Mutual labels:  activerecord
query-objects-example
Example of rails app using Query Objects
Stars: ✭ 37 (-44.78%)
Mutual labels:  activerecord
attribute-depends-calculator
Automatically calculate a collection of depends attribute of ActiveRecord
Stars: ✭ 41 (-38.81%)
Mutual labels:  activerecord
Mitm
Man in the middle tool
Stars: ✭ 30 (-55.22%)
Mutual labels:  audit
yii2-activerecord-inheritance
ActiveRecord Inheritance is an util to provide the Class Table Inheritance Pattern the to the Yii2 framework
Stars: ✭ 18 (-73.13%)
Mutual labels:  activerecord
git-version-bumper
Bump your git tag to the next version, easily. 👊
Stars: ✭ 92 (+37.31%)
Mutual labels:  versioning
sql-builder
A simple SQL builder for generate SQL for non-ActiveRecord supports databases
Stars: ✭ 34 (-49.25%)
Mutual labels:  activerecord
ecaudit
Ericsson Audit plug-in for Apache Cassandra
Stars: ✭ 36 (-46.27%)
Mutual labels:  audit

ActiveSnapshot

Gem Version CI Status RubyGems Downloads

Simplified snapshots and restoration for ActiveRecord models and associations with a transparent white-box implementation.

Key Features:

  • Create and Restore snapshots of a parent record and any specified child records
  • Predictible and explicit behaviour provides much needed clarity to your restore logic
  • Snapshots are created upon request only, we do not use any callbacks
  • Tiny method footprint so its easy to completely override the logic later

Why This Library:

Model Versioning and Restoration require concious thought, design, and understanding. You should understand your versioning and restoration process completely. This gem's small API and fully understandable design fully supports this.

I do not recommend using paper_trail-association_tracking because it is mostly a blackbox solution which encourages you to set it up and then assume its Just WorkingTM. This makes for major data problems later. Dont fall into this trap. Instead read this gems brief source code completely before use OR copy the code straight into your codebase. Once you know it, then you are free.

Installation

gem 'active_snapshot'

Then generate and run the necessary migrations to setup the snapshots and snapshot_items tables.

rails generate active_snapshot:install
rake db:migrate

Then add include ActiveSnapshot to your ApplicationRecord or individual models.

class ApplicationRecord < ActiveRecord::Base
  include ActiveSnapshot
end

This defines the following associations on your models:

has_many :snapshots, as: :item, class_name: 'Snapshot'
has_many :snapshot_items, as: :item, class_name: 'SnapshotItem'

It defines an optional extension to your model: has_snapshot_children.

It defines one instance method to your model: create_snapshot!

Using a different storage format

By default ActiveSnapshot encodes objects to JSON and stores in the database as plain text. If you prefer to have YAML encoded columns or native JSON DB columns you can configure this as follows:

ActiveSnapshot.config do |config|
  config.storage_method = "serialized_json" # default, for text column
  #config.storage_method = "serialized_yaml" # for text column
  #config.storage_method = "native_json" # for json/jsonb column
end

If using a native json column, you should configure the storage_method before generating the migration. If this step was missed then you would need to create a migration to change the :object and :metadata columns to json (or jsonb)

change_column :snapshots, :object, :json
change_column :snapshots, :metadata, :json

Basic Usage

You now have access to the following methods:

post = Post.first

# Create snapshot, all fields are optional
snapshot = post.create_snapshot!(
  identifier: "snapshot_1",
  user: current_user,
  metadata: {
    foo: :bar
  },
)

# Restore snapshot and all its child snapshots
snapshot.restore!

# Destroy snapshot and all its child snapshots
# must be performed manually, snapshots and snapshot items are NEVER destroyed automatically
snapshot.destroy!

Tracking Associated / Child Records

class Post < ActiveRecord::Base
  include ActiveSnapshot
  
  has_snapshot_children do
    ### Executed in the context of the instance / self

    ### Reload record from database to ensure a clean state and eager load the specified associations
    instance = self.class.includes(:tags, :ip_address, comments: [:comment_sub_records]).find(id)
    
    ### Define the associated records that will be restored
    {
      comments: instance.comments,
      
      ### Nested Associations can be handled by simply mapping them into an array
      comment_sub_records: instance.comments.flat_map{|x| x.comment_sub_records }, 
      
      tags: {
        records: instance.tags
      },
      
      ip_address: {
        record: instance.ip_address,
        delete_method: ->(item){ item.release! }
      }
    }
  end

end

Now when you run create_snapshot! the associations will be tracked accordingly

Reifying Snapshot Items

You can view all of the reified snapshot items by calling the following method. Its completely up to you on how to use this data.

reified_parent, reified_children_hash = snapshot.fetch_reified_items

As a safety these records have the @readonly = true attribute set on them. If you want to perform any write actions on the returned instances you will have to set @readonly = nil.

reified_parent, reified_children_hash = snapshot.fetch_reified_items

reified_parent.instance_variable_set("@readonly", false)

Key Models Provided & Additional Customizations

A key aspect of this library is its simplicity and small API. For major functionality customizations we encourage you to first delete this gem and then copy this gems code directly into your repository.

I strongly encourage you to read the code for this library to understand how it works within your project so that you are capable of customizing the functionality later.

  • SnapshotsConcern
    • Defines snapshots and snapshot_items has_many associations
    • Defines create_snapshot! and has_snapshot_children methods
  • Snapshot
    • Contains a unique identifier column (optional, but available for custom identification purposes)
    • has_many :item_snapshots
  • SnapshotItem
    • Contains object column which contains an encoded database row
    • belongs_to :snapshot

Credits

Created & Maintained by Weston Ganger - @westonganger

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].