如何使用 Ruby on Rails 中的映射表跟踪模型历史? [英] How to keep track of model history with mapping table in Ruby on Rails?
问题描述
我想记录用户何时更改地址.
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.
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 插件 是一个很好的解决方案.
下面摘自 http://github.com/laserlemon/vestal_versions强>
acts_as_versioned 来自 technoweenie 是一个很好的开始,但它未能跟上 ActiveRecord 在 2.1 版中引入的脏对象.此外,每个版本化模型都需要自己的版本表来复制原始表的大部分列.然后,版本表中填充了通常复制大部分原始记录属性的记录.总而言之,不是很干.
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 只需要一个版本表(与其父模型多态关联)并且对现有的没有任何改变表.但它通过存储仅模型更改的序列化哈希值,使 DRYer 更进一步.想想现代版本控制系统.通过遍历变更记录,可以将模型恢复到任意时间点.
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.
这正是 Vental_versions 所做的.模型不仅可以恢复到以前的版本号,还可以恢复到日期或时间!
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 版本插件这个:
有关详细信息,请参阅此截屏.
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
这篇关于如何使用 Ruby on Rails 中的映射表跟踪模型历史?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!