My question: Should I roll my own model versioning or use one of the versioning gems that's already out there? If I should use a gem, which one seems best for this application?
Info about my app
My app is a simple Checklist app. There are Checklists and Jobs, and I track user responses with Responses and Submissions. The Response tells me what the use said ("Done", with a note "We need more mops.") and the Submission tells me when that particular Checklist was filled out (because there may be many submissions and sets of responses for a given checklist). I'll show my associations below, in case that helps.
#checklist.rb
class Checklist < ActiveRecord::Base
has_many :jobs, :through => :checklists_jobs
has_many :submissions
end
#job.rb
class Job < ActiveRecord::Base
has_many :checklists, :through => :checklists_jobs
has_many :responses
end
#response.rb
class Response < ActiveRecord::Base
belongs_to :job
belongs_to :submission
belongs_to :user
end
#submission.rb
class Submission < ActiveRecord::Base
belongs_to :user
belongs_to :checklist
has_many :responses
end
What I'm trying to do with versioning
What I want to do is record users' responses to jobs on checklists. But I want to make sure that I can reproduce the original checklist (with response information) if the checklist changes. For example, I want to make sure I can answer this question for all previous versions of a checklist:
"What did the checklist look like, and what were the responses three Tuesdays ago?"
I don't want to lose the answer to that question if I change the checklist or any of its jobs.
I think the best way to do this is to use versioning (for jobs and checklists). For example, if a Job is changed (the name or description) by an admin, then I don't update the existing job, but create a new version and leave the old version intact. Then I just leave the old stuff in place and point the checklist to the new version of the job.
Should I use a gem or roll my own?
What I'm trying to decide is whether I should just roll my own (write code to increment the version, point everything to the version, and preserve the previous version) or use an existing solution. The two best solutions seem to be paper_trail and vestal_versions. I don't have enough reputation points to post more than two links, so I'll link to each of gem's Railscast (which will get you to the gem itself if you want). Railscast 255 Undo with paper_trail and Railscast 177 Model Versioning - 177 uses vestal_versions.
Pros to rolling my own:
Cons to rolling my own:
This seems important because whatever I decide I'll basically be stuck with. I don't think it will be easy to switch from one method to another later.
Use PaperTrail, and don't roll your own solution. I strongly disagree with Richard's answer. PaperTrail is a very active project, with many people contributing to bug fixes, supporting the latest Rails and Ruby versions, and handling gem conflicts.
If you don't like the way PaperTrail does something, you should fork it and change that behaviour. If it's a general improvement, submit a pull request so that we can all benefit from your work. Don't rewrite it from scratch, because you don't have the hindsight of bugs and edge-cases that the PaperTrail committers have already been through.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With