【问题标题】:Persist old ActiveRecord model attributes保留旧的 ActiveRecord 模型属性
【发布时间】:2013-07-11 17:03:09
【问题描述】:

我有一个名为 Client 的模型,它具有 3 个属性:姓名、电话和电子邮件。 一开始,我有一个带有一些值的客户端实例:Mark、+54261334455 和 fake@client.com。然后我将这些值更改为:Peter, +54261444444, another@mail.com 但我需要保留旧值。我该怎么做?

我的选择:

  1. 创建 old_attr 列:姓名、电话、电子邮件、old_name、old_phone 和 old_email。我认为这是一个丑陋的解决方案...
  2. 使用serialize 保留仅具有额外字段的旧数据:姓名、电话、电子邮件和数据。我认为这不是一个好主意,因为您需要多次操作旧数据。
  3. 创建 2 个客户端实例。一个带有旧数据,另一个带有新数据,向客户端模型添加了一个额外的字段来关联这些对象。我认为这是更好的解决方案,但由于将“一个客户端”一分为二,我需要增加很多逻辑

有更好的想法吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord rails-activerecord revision-history


    【解决方案1】:

    在您的情况下这可能有点矫枉过正,但有一些很棒的 ActiveRecord 版本控制工具。 它可以让您跟踪对特定记录所做的更改,甚至将值重置为以前的版本。

    我知道的最好的解决方案之一是paper_trail

    【讨论】:

      【解决方案2】:

      选项 4:创建一个与 Client 相同的 ClientHistory 模型,并添加一个引用相应 Clientclient_id 列。然后,before_save 回调可以执行以下操作:

      before_save :track_history
      
      def track_history
          return if(new_record? || !changed?)
          old = Hash[attribute_names.map { |name| [name == 'id' ? 'client_id' : name, self.send("#{name}_was")] }]
          ClientHistory.create!(old)
      end
      

      new_record? || !changed? 当然可以在before_save 调用中被推送到:if 选项。您可能希望过滤attribute_names 以排除更多内容,并且您可能只想跟踪已更改的内容,这两者都是非常微不足道的修改(但要注意如何跟踪到-nil 和从-nil 转换)。

      【讨论】:

      • 这个想法很像我的第一个选择。我不想在一两个表中重复属性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多