A few years ago, I described how to combine acts_as_paranoid and acts_as_versioned in order to make deleted records end up in your versioning tables.
In order to do the same thing under Rails 3, I had to make a few adjustments. First of all, you need the rails3_acts_as_paranoid gem, which is a total rewrite of acts_as_paranoid for rails 3. Add these lines to your Gemfile:
gem 'rails3_acts_as_paranoid' gem 'acts_as_versioned'
Then put a file in config/initializers with these contents:
module ActiveRecord
module Acts
module Versioned
def acts_as_paranoid_versioned(options = {})
acts_as_paranoid
acts_as_versioned options
# Override the destroy method. We want deleted records to end up in the versioned table,
# not in the non-versioned table.
self.class_eval do
def destroy()
with_transaction_returning_status do
run_callbacks :destroy do
# call the acts_as_paranoid delete function
self.class.delete_all(:id => self.id)
# get the 'deleted' object
tmp = self.class.unscoped.find(id)
# run it through the equivalent of acts_as_versioned's
# save_version(). We used to call that function but it is a
# noop when @saving_version is not set. That only gets done in
# a protected function set_new_version(). Easier to just
# replicate the meat of the save_version() function here.
rev = tmp.class.versioned_class.new
clone_versioned_model(tmp, rev)
rev.send("#{tmp.class.version_column}=", send(tmp.class.version_column))
rev.send("#{tmp.class.versioned_foreign_key}=", id)
rev.save
# and finally really destroy the original
self.class.delete_all!(:id => self.id)
end
end
end
end
# protect the versioned model
self.versioned_class.class_eval do
def self.delete_all(conditions = nil); return; end
end
end
end
end
end
I wonder if there is a more elegant way to achieve this…
Note: code updated at 2011-05-28 to make sure :dependent => :destroy on has_many associations does the right thing.
![[Play OGG]](/blog/wp-content/photos/play_ogg_small.png)
I fixed this issue directly, in my acts_as_versioned gem. See “Update”, at https://github.com/mjsommer/acts_as_versioned