Rails - 如何保存现有记录并将更新应用于副本?

时间:2017-07-05 20:32:39

标签: ruby-on-rails ruby

我有一个网页,可以跟踪包含大量变量的预算,这些变量存储在40多列中。随着时间的推移,对这些预算进行了调整,但我需要能够跟踪随时间和年度的变化。我尝试在我的模型中添加一个私有方法,该方法应该创建由:before_update 回调触发的现有记录的副本。但是,它不起作用。更新会更改现有记录,并且根本不会保留原始记录。

型号:

class Budget < ActiveRecord::Base

  before_update :copy_budget

  private

  def copy_budget
    @budget = Budget.find(params[:id])
    @budget.dup
    @budget.save
  end
end

我还在学习rails,(这是在Rails 4中),我认为这是最好的方法。如果没有,是否有更好的方法将表单设置为ALWAYS发布新记录而不是路由更新如果记录已经存在?

目前,form_for行如下所示:

<%= form_for(@budget) do |f| %>

除了没有发生的重复之外,一切都按预期工作。我错过了什么? .dup函数是否也可以复制:id?这是通过MySQL db中的自动增量来指定的,所以如果.dup正在复制一切,有没有办法将除了:id之外的所有数据复制到新记录中?

提前感谢任何建议。

1 个答案:

答案 0 :(得分:1)

dup方法返回没有id的新对象,它不会在适当的位置更新它。由于您的copy_budget方法已经是Budget上的实例方法,因此您也不需要(因为params不是,因此您甚至不能这样做在模型中可访问)通过id查找预算,而只是使用当前实例(self)。因此,以下更改将为您修复copy_budget方法,但您仍在复制已修改的对象,就在它被保存到数据库之前

def copy_budget
  copy_of_budget = self.dup
  copy_of_budget.save
end

它会按照您期望的方式运作。但是,您无法以任何方式将副本链接到当前版本的预算中(无法告知预算ID = 1是预算ID = 2的旧版本)。我推荐看一下像PaperTrail这样的宝石(我确定有很多其他的,如果那个不适合你的需要)已经经过了很多考虑保持历史记录变化的问题和特征。