ruby-on-rails – 如何使用Ruby on Rails中的映射表跟踪模型历史?

梦想

我想保留用户何时更改地址的记录.

这样,订单放置时,始终可以引用订单放置时使用的用户地址.

可能的模式

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
)

sql中,这可能看起来像:[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)
;

编辑:解决方

@KandadaBoggu发布了一个很棒的解决方案. Vestal Versions plugin一个很好的解决方案.

摘自http://github.com/laserlemon/vestal_versions的摘录

最后,DRY ActiveRecord版本控制!

07002 by 07003 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.

07004 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!

解决方法

为此使用 Vestal versions plugin

有关详细信息,请参阅this屏幕截图.

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

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...