belongs_to a specific version

237 Views Asked by At

I need to store the specific version of a model with an order. I'm planning to use a versioning gem like paper_trail or vestal_versions. I'd like the correct version automatically loaded with the order.

Ideally, I'd simply store the object with order.update_attributes(:stuff => bought_stuff) and the order would remember the version of the stuff so that subsequent loads would make order.reload.stuff still be the object as it was when the order was saved.

Is there a gem that would provide such a functionality? I couldn't find one.

Otherwise, how can I achieve that with ActiveRecord and a versioning gem?

2

There are 2 best solutions below

0
On

Actually, I could achieve almost what I want with PaperTrail and this :

class Stuff < ActiveRecord::Base
  has_paper_trail
end

class Order < ActiveRecord::Base
  belongs_to :stuff

  def stuff_with_version
    stuff_without_version.version_at(created_at) if stuff_without_version
  end

  alias_method_chain :stuff, :version
end
0
On

Not sure this is necessarily the best design for you, but you could use paper_trail for this. Simply add the macro method 'has_paper_trail' at the top of your model class and any time an instance changes, a serialised copy of it is created in a table called "versions" along with a polymorphic relationship back to the actual model.

Supposing you want to relate a particular version of a 'product' to an order, start by adding a relationship to the versions table - i.e. a migration that adds a 'version_id' to your order, and then set up the relationship as follows:

class Order
  belongs_to :version

  def product
    version
  end

  def product=(p)
    version=p.versions.last
  end

end

class Product
  has_paper_trail
end

Using this, when you add a product to an order, it will relate the order to the latest version of the product instead. When you retrieve the product, it will pull out the version; i.e. the product as it was when you created the order. Getting the relationship to work the other way around (i.e. relating products back to orders) might be more complicated, but this is a start.