Reputation: 3361
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
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:
It's easy to make your record non-draft (just change the flag)
you will not duplicate data (because practically you will have the same in draft and non-draft records)
coding will be easy, no complex login
all the data will be in one place and hence less room for error
Upvotes: 8
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
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
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
Reputation: 27789
Check out the Active Record Versioning category at The Ruby Toolbox. The current leader is Paper Trail.
Upvotes: 2