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

前端之家收集整理的这篇文章主要介绍了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
原文链接:https://www.f2er.com/ruby/266284.html

猜你在找的Ruby相关文章