我有一个网页,可以跟踪包含大量变量的预算,这些变量存储在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之外的所有数据复制到新记录中?
提前感谢任何建议。
答案 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这样的宝石(我确定有很多其他的,如果那个不适合你的需要)已经经过了很多考虑保持历史记录变化的问题和特征。