Acts As Draftable
Acts as Draftable is a Ruby on Rails plugin written by Rails core contributor Rick Olson (Techno Weenie) that facilitates the creation and modification of records as drafts before committing the changes to the database. It works its magic with the help of a secondary table that mimics the main one – containing the draftable fields and a foreign key field to link it to your actual table. This is a great tool if you want to review and then approve a post before publishing it.
Install the plugin:
script/plugin install http://svn.techno-weenie.net/projects/plugins/actsasdraftable/
Create a model (we’ll say you are doing movies with 2 field: name and director)
class Movie < ActiveRecord::Base end
Specify that your model is draftable and on what fields:
class Movie < ActiveRecord::Base actsasdraftable :fields => [:name, :director] end
Create a duplicate of your model with the fields you have specified and the _drafts suffix:
class MovieDrafts < ActiveRecord::Migration def self.up createtable :moviedrafts do |t| t.string :name t.string :director t.timestamps end end
def self.down droptable :moviedrafts end end
Instead of saving the record in your create method, you could save the draft
def create @movie = Movie.new(params[:movie]) respondto do |format| if @movie.savedraft
You might create a method to view the latest draft
def latest_draft @movie = Movie::Draft.find(:last) render :action => :show end
And then you might have a link to save that draft as an actual record – when you do this – the draft will be removed from the drafts table
def savedraft @movie = Movie::Draft.find(:last)
@movie = @movie.tomovieif @movie.save redirectto moviespath end end
If you already had a record and want a new draft of changes, same as step 5 – the save_draft method:
movie.save_draft
If you have a Movie loaded and want to then load and display the drafted changes
movie = Movie.find(1) movie.loadfromdraft
Now you might save the draft’s attributes over the current attributes
movie = Movie.find(1) movie.savefromdraft
If you want to create a draft when updating a record
@movie = Movie.find(params[:id]) @movie.attributes=(params[:movie]) respondto do |format| if @movie.savedraft
I am available for Ruby on Rails consulting work – get in touch to learn more.