如何在 Ruby on Rails 中使用映射表跟踪模型历史记录?

2023-11-22

dream

我想记录用户何时更改地址。

这样,当下订单时,它将始终能够引用下订单时使用的用户地址。

可能的图式

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 版本插件 is a 很好的解决方案.

下面的片段摘自http://github.com/laserlemon/vestal_versions

最后,DRY ActiveRecord 版本控制!

行为作为版本 by 技术知识这是一个很好的开始,但它未能跟上 ActiveRecord 在 2.1 版本中引入脏对象的步伐。此外,每个版本化模型都需要自己的版本表,该表复制原始表的大部分列。然后,版本表中会填充通常与原始记录的大部分属性重复的记录。总而言之,不是很干。

维斯塔版本仅需要一个版本表(与其父模型多态关联),并且无需对现有表进行任何更改。但它通过存储序列化的哈希值来实现更干燥的一步only模型的变化。想想现代版本控制系统。通过遍历更改记录,可以将模型恢复到任何时间点。

这正是 Vestal_versions 所做的。模型不仅可以恢复到以前的版本号,还可以恢复到日期或时间!


Use the Vestal 版本插件为了这:

参考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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Ruby on Rails 中使用映射表跟踪模型历史记录? 的相关文章

随机推荐