【问题标题】:Clone (a.k.a. duplicate) a Record克隆(又名重复)记录
【发布时间】:2011-01-05 10:18:03
【问题描述】:

我需要复制一条记录,除了源 ID 之外,它具有与原始相同的属性。我愿意:

在视图中:

<%= link_to "Duplicate", :action => "clone", :id => Some_Existing_ID %>

在控制器中:

def clone
  @item = Item.find(params[:id]).clone

  if @item.save
    flash[:notice] = 'Item was successfully cloned.'
  else
    flash[:notice] = 'ERROR: Item can\'t be cloned.'
  end

  redirect_to(items_path)
end      

但是什么也没发生!在控制台中,我发现克隆会生成没有 ID 的副本。

有什么想法吗?

*> 顺便说一句:我正在运行 Rails 2.3.5 和 Ruby 1.8

【问题讨论】:

  • 我尝试做同样的事情,它对我有用。克隆应该生成没有 ID 的副本,因为 ID 设置为在保存时记录。我会添加一些logger.debug 并在日志中检查克隆操作中发生的情况。也许路线有问题?
  • 警告 在 Rails 3 中,不要调用 clone,而是调用 dupstackoverflow.com/questions/60033/…

标签: ruby-on-rails


【解决方案1】:

避免使用克隆方法。它不再受支持。 clone 方法现在委托使用 Kernel#clone 来复制对象的 id。

# rails < 3.1
new_record = old_record.clone

# rails >= 3.1
new_record = old_record.dup

【讨论】:

    【解决方案2】:

    确保默认的克隆行为适合您。根据您的验证规则,克隆的记录实际上可能是无效的。

    尝试使用@item.save! 代替@item.save 并检查是否引发异常。 您也可以直接在控制台实例中尝试代码。

    In Console I figured out that clone generates the copy without ID.
    

    确实如此。 #clone 实际上创建了一个克隆但不保存记录。 这就是为什么您需要在您的操作中调用 save 方法,这就是您实际执行的操作

    if @item.save # <-- here you save the record
      flash[:notice] = 'Item was successfully cloned.'
    else
      flash[:notice] = 'ERROR: Item can\'t be cloned.'
    end
    

    【讨论】:

    • 使用 Item.save!我发现验证正在弹出。谢谢!
    【解决方案3】:

    在脚本/控制台中这对我有用

    >> i = Item.find(:first)
    => #<Item id: 1, name: "Item 1", description: "This is item 1!", created_at: "2010-01-03 21:51:49", updated_at: "2010-01-05 18:25:42">
    >> i2 = i.clone
    => #<Item id: nil, name: "Item 1", description: "This is item 1!", created_at: "2010-01-03 21:51:49", updated_at: "2010-01-05 18:25:42">
    >> i2.save
    => true
    >> i2
    => #<Item id: 2, name: "Item 1", description: "This is item 1!", created_at: "2010-01-03 21:51:49", updated_at: "2010-01-05 18:25:42">
    

    克隆确实不会增加 id 字段(合乎逻辑,因为这是一个数据库操作)。保存项目后,id 现在更新,我的数据库包含克隆。

    所以它应该工作......你也可以在你的控制台中尝试这个,看看它是否正常工作或者它是否像你的例子一样失败。您也可以拆分第一行,因此找到原始并将其克隆到一个新变量中并将(logger.debug @item.inspect)都打印到控制台以查看克隆是否成功。保存后还打印克隆的项目以查看是否有更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-13
      • 2016-04-11
      • 2021-01-07
      • 2012-12-23
      • 1970-01-01
      • 2020-03-04
      相关资源
      最近更新 更多