How to keep track of model history with mapping table in Ruby on Rails?

activerecord, ruby-on-rails, schema

Solution

Use the Vestal versions plugin for this:

Refer to this screen cast for more details.

class Address < ActiveRecord::Base
  belongs_to :user
  versioned
end


class Order < ActiveRecord::Base
   belongs_to :user

   def address
     @address ||= (user.address.revert_to(updated_at) and user.address)
   end
end

Problem

dream I'd like to keep record of when a user changes their address. This way, when an order is placed, it will always be able to reference the user address that was used at the time of order placement. possible schema ``` users ( id username email ... ) user_addresses ( id label line_1 line_2 city state zip ... ) user_addresses_map ( user_id user_address_id start_time end_time ) orders ( id user_id user_address_id order_status_id ... created_at updated_at ) ``` in sql, this might look something like: [sql] ``` select ua.* from orders o join users u on u.id = o.user_id join user_addressses_map uam on uam.user_id = u.id and uam.user_address_id = o.user_address_id join user_addresses ua on ua.id = uam.user_address_id and uam.start_time < o.created_at and (uam.end_time >= o.created_at or uam.end_time is null) ; ``` edit: The Solution @KandadaBoggu posted a great solution. The Vestal Versions plugin is a great solution. snippet below taken from http://github.com/laserlemon/vestal_versions Finally, DRY ActiveRecord versioning! acts_as_versioned by technoweenie was a great start, but it failed to keep up with ActiveRecord’s introduction of dirty objects in version 2.1. Additionally, each versioned model needs its own versions table that duplicates most of the original table’s columns. The versions table is then populated with records that often duplicate most of the original record’s attributes. All in all, not very DRY. vestal_versions requires only one versions table (polymorphically associated with its parent models) and no changes whatsoever to existing tables. But it goes one step DRYer by storing a serialized hash of only the models’ changes. Think modern version control systems. By traversing the record of changes, the models can be reverted to any point in time. And that’s just what vestal_versions does. Not only can a model be reverted to a previous version number but also to a date or time!

Original source