同时更新和创建新实例

时间:2016-05-09 14:40:42

标签: ruby-on-rails-4

当用户更新发票表单时,我想创建一个包含更新属性的发票记录,但也要更改旧记录的一个或两个字段并保存。

控制器动作的轮廓怎么样才能实现呢?

3 个答案:

答案 0 :(得分:1)

我没有使用控制器操作,而是使用回调函数将代码放入模型中:

  before_save do |rec|
    if !rec.new_record?
      attrb = rec.attributes.delete_if{|k, v| ["id"].include? k }
      Book.create(attrb)

      rec.restore_attributes
      rec.year = rec.year + 2 # some custom change
      true
    end
  end

我保留所有属性,除非'id'(否则我得到一个错误)用于创建具有新属性的新记录。 然后我恢复现有记录的属性。我在保存之前做了一些自定义更改。

答案 1 :(得分:1)

我对Rails很新,但这看起来非常简单。如你所说,用户正在更新"发票,您的控制器视图可能已经传递给用户可用的所有数据以进行进一步更改。

提交表单时,您的更新操作可以轻松更新当前记录数据,并在此基础上创建新记录数据

虽然它是自动化的,但您需要说清楚:

  • 如果每次发票记录为
    时都创建新的发票记录 更新(可以创建相同发票的大量副本)
  • 如何将旧记录设为存档以避免重复
  • 可以'额外"修正案可自动化,并可通过算法轻松处理......

答案 2 :(得分:0)

嵌套属性使事情变得有点棘手。因此,为了创建新实例,我必须对资源及其嵌套项使用dup方法。

通常,建议保持控制器的纤薄,使模型变胖。不过,我已决定将此代码包含在我的Invoices控制器中:

def revise_save
  @contact = Contact.find(params[:contact_id])
  @invoice = @contact.invoices.find(params[:invoice_id])
  @invoice_old = @invoice.dup
  @invoice.invoice_items.each do |item|
    @invoice_old.invoice_items << item.dup
  end

  @invoice.datum = DateTime.now.to_date

  # archive old invoice
  # @invoice_old. ...

  @invoice_old.save

  # make old new invoice

  @invoice.datum = Time.now
  # ...
  @invoice.update(invoice_params)

  redirect_to invoices_path 

end

请注意,在此解决方案中,当前编辑的(原始)发票成为新发票,旧发票自相矛盾地创建。

感谢@ iwan-b指出我正确的方向。