2011-04-19 165 views
10

我有一個嵌套表單,一旦保存,我希望能夠單擊顯示頁面上的鏈接來複制或克隆該表單並打開一個新表單。從那裏我應該能夠進行編輯(如新ID)並保存爲新記錄。我看過一些例子,如deep_cloneable gem,但我不知道如何實現它。我認爲這應該很簡單,但我不明白把東西放在控制器和放映視圖中的位置。Rails克隆副本或副本

回答

17

如果你想複製一個ActiveRecord對象,你可以使用它的屬性創建新的像

,你可以在你的控制器,可以在鏈路被稱爲動作,

def create_from_existing 
@existing_post = Post.find(params[:id]) 
#create new object with attributes of existing record 
@post = Post.new(@existing_post.attributes) 
render "your_post_form" 
end 
+0

謝謝,所以之後在我的控制器中,link_to標記應該如何在視圖中查找? – FattRyan 2011-04-19 04:22:14

+0

你是新來的鐵路? 在顯示頁面上,您需要渲染一些鏈接,如link_to「Copy to new record」,{:controller =>「your controller」,:action =>'create_from_existing',:id => params [:id]} 也,爲create_from_existing操作定義路由inroute.rb文件。 如果你想在現有頁面上顯示這個表單,那麼你可以使用ajax使用link_to_remote(link_to:remote => true,rails 3) – 2011-04-19 04:29:34

+1

這個句柄怎麼處理has_many?它是爲子對象創建新記錄還是使用相同的記錄? – Mike 2013-02-03 16:06:49

3
class Foo < ActiveRecord::Base 
    def self.clone_from(parent) 
    parent = find(parent) unless parent.kind_of? Foo 
    foo = self.new 
    foo.attributes = parent.attributes 
    # if you want to also clone a habtm: 
    foo.some_association_ids = parent.some_association_ids 
    # etc. 
    foo 
    end 
end 

class FoosController < ApplicationController 
    def clone 
    foo = Foo.clone_from(params[:id]) 
    respond_with(foo) 
    end 
end 
17

我發現這些答案有點難以遵循。一個答案顯示了這一點:

@post = Post.new(@existing_post.attributes) 

這將無法正常工作,因爲它也會傳遞id和timestamp值。我用.dup來解決這個問題,並在我的答案中顯示出來。

以下是我如何從現有項目中創建新項目。

該模型用於產品,控制器Products_Controller.rb。我們將向控制器添加一個名爲COPY的新動作,我們將從現有產品的SHOW視圖鏈接到它,並呈現填充的NEW視圖以備編輯和保存。

首先,我們創建routes.rb中用於複製操作的路線

resources :Products do 
    member do 
     get 'copy' 
    end 
    end 

然後在Products_controller.rb

複製動作
def copy 
     @source = Product.find(params[:id]) 
     @product = @source.dup 
     render 'new' 
     end 

現在,我們需要一個鏈接添加到SHOW視圖致電我們的複製行爲。

<%= link_to "copy", copy_product_path(params[:id]) %> 

這爲我工作。我希望它對你有用,答案很簡單,可以遵循。

1

另外值得一提的是模型上的dup方法。它複製了所有屬性和外向關係,但將id設置爲nil。像這樣(從Naren Sisodiya借來的代碼):

def create_from_existing 
    @existing_post = Post.find(params[:id]) 
    #create new object with attributes of existing record 
    @post = @existing_post.dup 
    render "your_post_form" 
end