Rails 3.2 app - Should I use a versioning gem (paper_trail or vestal_versions) or handle it manually?
B

2

7

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:

  • I need to report on all historical data by reconstructing checklists and their responses. This is a main feature of the app. It seems like this will be tricky with the gems I mentioned.
  • I'll be able to report on groups of versions ("I want to see all responses for any version of this Job"). That seems easy this way.

Cons to rolling my own:

  • It's going to be tricky because I have several has_many :through associations. I'll have to be really careful to update all the tables and join tables correctly. (This may also be an issue with one of the gems).
  • Since I'm using this version data for reporting, I'm concerned about performance issues. Parsing hashes seems computationally expensive, whereas relying on flat tables with indexes seems pretty efficient.
  • Both gems seem more geared to keeping version history for tracking, and not really for maintaining historical information for reporting purposes.

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.

Bratwurst answered 5/3, 2013 at 22:38 Comment(0)
E
-4

My experience is that when you ask the question about making your own solution versus using a third-party solution the answer is almost always 'roll your own.' Not only can you make EXACTLY what you want in terms of functionality, you're not beholden to some other developer to:

  1. Fix their bugs
  2. Support the latest rails update/ruby update, etc.
  3. Not conflict in some way with your app in subtle ways you can't address (require different versions of dependent gems).

I say that if you have the ability you should spend the time and write exactly what you want. It will pay off big time two years from now.

Executory answered 5/3, 2013 at 22:59 Comment(8)
Richard, this is a great answer. I'm going to hold off a bit on voting it the preferred answer just in case someone has something more pointed, but I like your reasoning and agree with it. Thanks for your thoughtful response!Bratwurst
Did you end up rolling your own?Albumose
Alex, I did end up rolling my own. It was very difficult, but I think it was probably best. I will need to do some reporting and analytics with historical data, and it's important that I have access to the original objects to do the reporting. The downside is I may have over-engineered my solution (and hence made it too difficult). I won't know if that's true until I really start running the app through it's paces.Bratwurst
Alex, I posted a lot of the code I used to roll my own in this thread: #15648896Bratwurst
or for example never update the vestal_version gem to support rails 4 , not that I am bitter or anythingCongelation
I find it odd that this answer is promoting a "Not Invented Here" philosophy. Absolutely, there are times to roll your own solution to a problem but overall I would say the opposite is true. If you can use a pre-built solution to a known problem, then that is almost always the better choice. You get a lot for free, INCLUDING the initial source code and bug fixes and you can always fork to fix bugs yourself. I would ask Richard, does he roll his own ORM instead of ActiveRecord, his own CGI library instead of Rack, his own http library instead of nethttp or typheous?Unearthly
Have to agree with the critics here. When there are widely used, supported, and stable third party libraries you should use them. They will cover many edge cases you won't think of, be tested, have features you don't have time to implement, and save you lots of time. There is definitely a place for rolling your own - when third party libraries are not implemented well, or it's a core competence. This is not one of them.Kimikokimitri
Downvoting for the same reasons as fregas and Alex Neth. In general, there is no benefit to reimplementing what someone else has already done, unless it won't work well for your needs (or unless you can do it significantly better).Klee
A
49

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.

Anaplastic answered 10/5, 2013 at 5:33 Comment(1)
Have to agree with this sentiment. When you're short for hours to code, getting functionality without having to update it yourself is a positive. You don't have to spend extra hours to maintain a library yourself for only marginal gains. This is Ruby, it's easier to add a little functionality that you do need (and run said tests on it), and push upstream, or keep local with open-closed principles against your application.Fortis
E
-4

My experience is that when you ask the question about making your own solution versus using a third-party solution the answer is almost always 'roll your own.' Not only can you make EXACTLY what you want in terms of functionality, you're not beholden to some other developer to:

  1. Fix their bugs
  2. Support the latest rails update/ruby update, etc.
  3. Not conflict in some way with your app in subtle ways you can't address (require different versions of dependent gems).

I say that if you have the ability you should spend the time and write exactly what you want. It will pay off big time two years from now.

Executory answered 5/3, 2013 at 22:59 Comment(8)
Richard, this is a great answer. I'm going to hold off a bit on voting it the preferred answer just in case someone has something more pointed, but I like your reasoning and agree with it. Thanks for your thoughtful response!Bratwurst
Did you end up rolling your own?Albumose
Alex, I did end up rolling my own. It was very difficult, but I think it was probably best. I will need to do some reporting and analytics with historical data, and it's important that I have access to the original objects to do the reporting. The downside is I may have over-engineered my solution (and hence made it too difficult). I won't know if that's true until I really start running the app through it's paces.Bratwurst
Alex, I posted a lot of the code I used to roll my own in this thread: #15648896Bratwurst
or for example never update the vestal_version gem to support rails 4 , not that I am bitter or anythingCongelation
I find it odd that this answer is promoting a "Not Invented Here" philosophy. Absolutely, there are times to roll your own solution to a problem but overall I would say the opposite is true. If you can use a pre-built solution to a known problem, then that is almost always the better choice. You get a lot for free, INCLUDING the initial source code and bug fixes and you can always fork to fix bugs yourself. I would ask Richard, does he roll his own ORM instead of ActiveRecord, his own CGI library instead of Rack, his own http library instead of nethttp or typheous?Unearthly
Have to agree with the critics here. When there are widely used, supported, and stable third party libraries you should use them. They will cover many edge cases you won't think of, be tested, have features you don't have time to implement, and save you lots of time. There is definitely a place for rolling your own - when third party libraries are not implemented well, or it's a core competence. This is not one of them.Kimikokimitri
Downvoting for the same reasons as fregas and Alex Neth. In general, there is no benefit to reimplementing what someone else has already done, unless it won't work well for your needs (or unless you can do it significantly better).Klee

© 2022 - 2024 — McMap. All rights reserved.