I was recently building an app which needed to take advantage of versioning. I liked the look of acts_as_versioned, which is a nice add-on to Rails to versions models.
However, the tutorial-fu is pretty sparse, and what is out there is pretty old, so I wanted to write up what it took to get it running for me.
Step 1 – The basics
First, create a new Rails app (
rails testversioning). I’m using the Rails default of not using MySQL here, but it should be similar. We’ll also need to install acts_as_versioned –
gem install acts_as_versioned. Change to the root of the rails application you just created.
Next, we need to make a tweak. There is a bug with Rails 2.1 and acts_as_versioned which is fixed in the trunk, but hasn’t made it to the release (which is 0.2.3 as of this post). To fix that, head over to GitHub, then click on the “Download” link which is next to the title near the center of the page. You can pick either the .zip or the .gz file. Extract the archive to the
vendor/plugins/acts_as_versioned folder in your rails application.
We’ll need to do one other thing. So Rails can see the gem, open up
config/environment.rb. Find the commented out lines around which start with config.gem (around line 30). Add the following line:
config.gem "acts_as_versioned", then save the file.
Step 2 – Basic Model
Let’s go ahead and get a basic model working. From the root of your rails app, type
script/generate scaffold Item title:string due_date:date status:string. This creates a basic model which lets you edit Items.
Now, we’ll need to tell the database about this model, so run
rake db:migrate. This runs the migration script at db/migrations and gets your database ready.
Now, go ahead and run
script/server and navigate to http://localhost:3000/Items. Feel free to add a new item. Make sure that’s all working before we move on.
Step 3 – Adding Versioning
Now that we know our base stuff is working, let’s get versioning working. This will consist of three steps:
- Create a migration for our versioning table
- Mark our model as versioned
- Use the versioning to do something meaningful
To create a migration for our table, we run the handy
script/generate migration AddVersioning – the last part is just a handy name to remember why we are doing this versioning. Open up the file just created in
db/migrate/[timestamp]_add_versioning.rb. Change the file so it looks like:
class AddVersioning < ActiveRecord::Migration
This may require tweaking if you have larger models where you don’t want to version all of the fields, but this will get us going for now. Now save the file.
Of course, that magic method we’re calling on our Item model is useless unless it knows what to do with it. So open up
app/models/item.rb and make it look like:
class Item < ActiveRecord::Base
Yep. Really. That’s it. Convention over configuration is a magic thing. Let’s let our database know about these changes – so call
Now, just to make sure nothing has been broken, fire up
script/server, navigate to your Items, and edit one. Everything should be fine.
Now we have to do something meaningful with the versioning information. Open up
app/views/items/show.html.erb. Before the Edit and Back links, put the following:
- <% for version in @item.versions.reverse %>
- <%=version.status %> (<%=version.updated_at %>)
<% end %>
Now save, and view the item you’ve edited. Edit it some more, and watch the version expand out. Yes, it really was that easy! There’s lots more to be learned from the RubyDocs, but hopefully that gets you going. Happy versioning!
Links that helped: