Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
/ snaps Public

Revisioning and tagging of ActiveRecord models.

License

Notifications You must be signed in to change notification settings

codevise/snaps

Open more actions menu

Repository files navigation

Snaps

Gem Version Build Status Test Coverage Code Climate

Revisioning and tagging of ActiveRecord models.

Installation

Add this line to your application's Gemfile:

gem 'snaps'

And then execute:

$ bundle

Run the install generator:

$ rake snaps:install:migrations

Migrate your database to create the snaps_tags table:

$ rake db:migrate

Basics

Snaps maintains a table of "named pointers" called Tags to other models. Implemented as a polymorphic association. Revisions are kept in the original table and identified by a perma_id field.

Snaps provides methods to create copies (snapshots) of models and tag these snapshots as needed.

Usage Examples

Basic Usage

A model that is to be revisioned with snaps needs an integer field called perma_id and must include the mixin created by Snaps.revision.

# db/migrate/xxx_create_posts.rb
create_table :posts do |t|
  t.integer(:perma_id)

  t.string(:title)
  t.text(:body)
end


# app/models/post.rb
class Post < ActiveRecord::Base
  include Snaps.revision
end

Now you can create snapshots of your post instances.

post = Posts.create(body: 'Some text')
post_snapshot = post.snapshot!

post.perma_id == post_snapshot.perma_id # => true

Using Snaps Tags you can assign one revision to be a 'draft'.

post.perma_id # => 25
post.snaps_tag!(:draft)

draft = Post.with_snaps_tag(:draft).find_by_perma_id(25)

Using a default Tag

It's easy to create a workflow in which a new post will be tagged by default. Also it's convenient to hide calls to with_snaps_tag in a scope on your domain models.

# app/models/post.rb
class Post < ActiveRecord::Base
  include Snaps.revision(default_tag: :draft)

  scope :drafts, -> { with_snaps_tag(:draft) }
end

# in controller
draft = Post.create(body: 'Some Text')

existing_draft = Post.drafts.find_by_perma_id(25)

draft.update(body: "New text")
draft.snapshot!

Managing Lifecycle of records with tags

# app/models/post.rb
class Post < ActiveRecord::Base
  include Snaps.revision(default_tag: :draft)

  scope :drafts, -> { with_snaps_tag(:draft) }
  scope :published, -> { with_snaps_tag(:published) }

  def publish
    snapshot!(tag: :published)
  end
end

# in controller
draft = Post.drafts.find_by_perma_id(25)
draft.publish

all_published_posts = Post.published

Revisioning composite models

# db/migrate/xxx_create_sections.rb
create_table :sections do |t|
  t.integer(:perma_id)
  t.references(:post)

  t.text(:body)
end

# app/models/section.rb
class Section < ActiveRecord::Base
  include Snaps.revision

  belongs_to :post
end

# app/models/post.rb
class Post < ActiveRecord::Base
  include Snaps.revision(default_tag: :draft,
                         components: [:sections])

  has_many :sections

  scope :drafts, -> { with_snaps_tag(:draft) }
  scope :published, -> { with_snaps_tag(:published) }

  def publish
    snapshot!(tag: :published)
  end
end

# in controller

draft = Post.drafts.find_by_perma_id(25)
draft.sections.create(body: "Section text")
post = draft.snapshot!

# snapshots of sections have been created

draft.sections.first.id != post.sections.first.id
draft.sections.first.body == post.sections.first.body

Accessing other revisions of a record

post.snaps_revisions.where('created_at < ?', post.created_at)

About

Revisioning and tagging of ActiveRecord models.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  
Morty Proxy This is a proxified and sanitized view of the page, visit original site.