Acts As Draftable
Saturday 15 November 2008
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/acts_as_draftable/ - 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 acts_as_draftable :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 create_table :movie_drafts do |t| t.string :name t.string :director t.timestamps end end def self.down drop_table :movie_drafts end end - Instead of saving the record in your create method, you could save the draft
def create @movie = Movie.new(params[:movie]) respond_to do |format| if @movie.save_draft - 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 save_draft @movie = Movie::Draft.find(:last) @movie = @movie.to_movie if @movie.save redirect_to movies_path 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.load_from_draft - Now you might save the draft's attributes over the current attributes
- If you want to create a draft when updating a record
@movie = Movie.find(params[:id]) @movie.attributes=(params[:movie]) respond_to do |format| if @movie.save_draft
movie = Movie.find(1)
movie.save_from_draft

Comments