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.

  1. Install the plugin:
    script/plugin install
    http://svn.techno-weenie.net/projects/plugins/acts_as_draftable/
  2. Create a model (we'll say you are doing movies with 2 field: name and director)
    class Movie < ActiveRecord::Base
    end
    
  3. Specify that your model is draftable and on what fields:
    class Movie < ActiveRecord::Base
      acts_as_draftable :fields => [:name, :director]
    end
    
  4. 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
    
  5. 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
    
  6. You might create a method to view the latest draft
    def latest_draft
      @movie = Movie::Draft.find(:last)
      render :action => :show
    end
    
  7. 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
    
  8. If you already had a record and want a new draft of changes, same as step 5 -- the save_draft method:
    movie.save_draft
    
  9. If you have a Movie loaded and want to then load and display the drafted changes
    movie = Movie.find(1)
    movie.load_from_draft
    
  10. Now you might save the draft's attributes over the current attributes
  11. movie = Movie.find(1)
    movie.save_from_draft
    
  12. 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
    

Comments

blog comments powered by Disqus