CrudVision - Lisa Seelye

July 2, 2007

I did something evil today

Filed under: rails, work — Lisa Seelye @ 21:07

I did something quite evil today at work.

A customer wants to be able to roll back changes made by its moderators. If there's a difference of opinion they want to roll back a change. Makes sense. (No, it isn't a wiki.)

I decided that a second-best effort (instead of doing:

RUBY:
  1. AdminEditLog.create(:user => @session_user, :description => "Set object=#{@object.inspect}")

I'd do:

RUBY:
  1. old = Marshal.dump(@object)
  2. @object.update_attributes(params[:object])
  3. AdminEditLog.create(:user => @session_user, :old => old, :current => Marshal.dump(@object.reload))

Why is it evil? It requires two BLOB fields in MySQL, stores the ENTIRE object, twice and can't be searched upon.

The next iteration will likely just be a diff. Something like:

RUBY:
  1. def object_diff(o,c)
  2. changes = {}
  3. c.attributes.each do |k,v|
  4. if o[k] != v
  5. changes[k.to_sym] = v
  6. end
  7. end
  8. changes
  9. end
  10. Marshal.dump(object_diff(old_obj,new_obj)) # Store this, works for the arbitrary models

It is just a little better. They want to revert back to it so there's no need to do the diff after, upon reverting.

It works and I was impressed how easy it was because the revert action is simply to Marshal.load the old object and to just .save it.

Ruby is love. Just don't abuse it by stuffing crap into the database!

Powered by WordPress