Matthew Hui
Matthew Hui

Reputation: 3361

Rails - Good way to support creation of drafts for several models

I want to allow users to create drafts of several models (such as article, blog post etc). I am thinking of implementing this by creating a draft model for each of my current models (such as articleDraft, blogpostDraft etc.). Is there a better way to do this? Creating a new model for every existing model that should support drafts seems messy and is a lot of work.

Upvotes: 4

Views: 1713

Answers (5)

sameera207
sameera207

Reputation: 16629

I think the better was is to have a flag in the table (ex: int column called draft), to identify if the record is a draft or not.

Advantages of having such a column with out a separate table, as I can see:

  1. It's easy to make your record non-draft (just change the flag)

  2. you will not duplicate data (because practically you will have the same in draft and non-draft records)

  3. coding will be easy, no complex login

  4. all the data will be in one place and hence less room for error

Upvotes: 8

Chris Peters
Chris Peters

Reputation: 18090

I've been working on Draftsman, a Ruby gem for creating a draft state of your ActiveRecord data.

Draftsman's default approach is to store draft data for all drafted models in a single drafts table via a polymorphic relationship. It stores the object state as JSON in an object column and optionally stores JSON data representing changes in an object_changes column.

Draftsman allows for you to create a separate draft model for each model (e.g., article_drafts, blog_post_drafts) if you want. I agree that this approach is fairly cumbersome and error-prone.

The real advantage to splitting the draft data out into separate models (or to just use a boolean draft flag on the main table, per sameera207's answer) is that you don't end up with a gigantic drafts table with tons of records. I'd offer that that only becomes a real problem when your application has a ton of usage though.

All that to say that my ultimate recommendation is to store all of your draft data in the main model (blog) or a single drafts table, then separate out as needed if your application needs to scale up.

Upvotes: 4

Georg Ledermann
Georg Ledermann

Reputation: 2752

Having a flag in the model has some disadvantages:

  • You can not save as draft unless the data is valid. Sure, you can skip validations in the Rails model, but think about the "NOT NULL" columns defined in the database

  • To find the "real" records, you have to use a filter (like "WHERE draft = FALSE"). This can slow down query performance.

As an alternative, check out my gem drafting. It stores drafts for different models in a separate table.

Upvotes: 1

simonmorley
simonmorley

Reputation: 2804

I'd go down the state machine route. You can validate each attribute when the model's in a certain state only. Far easier than multiple checkboxes and each state change can have an action (or actions) associated with it.

Upvotes: 1

Mori
Mori

Reputation: 27789

Check out the Active Record Versioning category at The Ruby Toolbox. The current leader is Paper Trail.

Upvotes: 2

Related Questions