Acts_as_versioned quirks

The Rails plugin acts_as_versioned by Rick Olson is a blessing when one wants to do some simple versioning. Building a wiki springs into mind which was exactly what I wanted to use it for. Following the learn_to post I was able to get most of it working. However I my case, and I imagine others, I did not want to version control my entire pages table. I do not care about the @created_at@ and @updated_at@ fields to be versioned. But using the default migration tactic of building a versioned table did not work (passing a block to the Page.create_versioned_table). Instead I needed to configure my model with:

self.non_versioned_columns << 'project_id' << 'project_user_id' << 'locked_by' << 'locked_at' << 'created_at' << 'updated_at'

Not something I would expect.

And it turned out there were more unexpected ‘features’. The inclusion of the timestamps in my Page model seemed superfluous. The generated @page_versions@ table included them by default. But there is no easy way for dropping these columns from the @pages@ table. Sure I could write a migration doing just that but by then the generated @page_versions@ table already contained these columns and apparently the generated class Page::Version referenced to these column. This obviously led to errors. Instead I ended up dropping and recreating the entire table. Unfortunately MySQL died complaining that the column @version@ already exists in the @pages@ table. You’ll have to remove that column too.

Finding a previous version has changed somewhat too. According to Rails Recipes;


>> p = Page.find(:first)
>> p = p.find_version(3)
NoMethodError: undefined method `find_version' for #<Page:0x329a5d8>

This should work but it does not. Actually I would love for it to work like that. The alternative is;


>> p = Page.find(:first)
>> array = Page.find_versions(:first)
>> p = p.revert_to(arr[2])

Not as pretty but it works.

On the bright side there is this neat feature called @:if_changed@. This allows you to control when a new version should be created. The directive is given as an argument in the acts_as_versioned declaration:

acts_as_versioned :if_changed => [:title, :text, :member_id]

Sweet now a new version is created only when the title, the text or the owner changes.

In conclusion, the acts_as_versioned plugin is a great extension but seems a bit outdated as not all functionality works(at least not in Rails 2.0RC1). Also it is better to create the documentation from the source as all the online documentation is very old.

One Response to “Acts_as_versioned quirks”

  1. erik scheirer Says:

    Great blog, thanks. I just now ran into the fact that find_version(X) is not working, would be nice to have that working, indeed. Don’t have time to post the fix, but wanted to say thanks for the time you took to post here, good sanity check for folks in the often murky acts_as_xxx world.

Leave a Reply