我.clone -ing在軌道記錄...在rails中克隆記錄,是否可以克隆關聯和深度複製?
new_blerg = Blerg.find(1).clone
這個紀錄負載和協會的負荷,這些關聯甚至有關聯。
有沒有辦法深入複製記錄並將其克隆,以便克隆所有這些關聯?
我.clone -ing在軌道記錄...在rails中克隆記錄,是否可以克隆關聯和深度複製?
new_blerg = Blerg.find(1).clone
這個紀錄負載和協會的負荷,這些關聯甚至有關聯。
有沒有辦法深入複製記錄並將其克隆,以便克隆所有這些關聯?
你可能會得到一些很好的利用了Amoeba gem的ActiveRecord的3.2。
它支持的has_one
,has_many
和has_and_belongs_to_many
協會,場預處理和既能到模型和在運行時被施加的高度靈活和強大的配置DSL容易和自動遞歸重複。
一定要檢查出Amoeba Documentation但使用是很容易的......
只是
gem install amoeba
或添加
gem 'amoeba'
您的Gemfile
然後添加變形蟲塊到你的模型,像往常一樣運行dup
方法
class Post < ActiveRecord::Base
has_many :comments
has_and_belongs_to_many :tags
amoeba do
enable
end
end
class Comment < ActiveRecord::Base
belongs_to :post
end
class Tag < ActiveRecord::Base
has_and_belongs_to_many :posts
end
class PostsController < ActionController
def some_method
my_post = Post.find(params[:id])
new_post = my_post.dup
new_post.save
end
end
新的崗位應具備原先與它相關聯的所有標籤,所有的意見應該被複製爲好。你可以通過DSL,您可以在文檔中讀到禁用的各種記錄的重複,但舉例來說,如果你想保持標籤,但沒有評論,你可以做這樣的事情:
class Post < ActiveRecord::Base
has_many :comments
has_and_belongs_to_many :tags
amoeba do
include_field :comments
end
end
或使用專用語法
class Post < ActiveRecord::Base
has_many :comments
has_and_belongs_to_many :tags
amoeba do
exclude_field :comments
end
end
,或者通過指定字段類型識別哪個(正是如此複製)
class Post < ActiveRecord::Base
has_many :comments
has_and_belongs_to_many :tags
amoeba do
recognize :has_and_belongs_to_many
end
end
每個這些不同的選項應該重新導致將新帖子與舊帖子的標籤重新關聯,但沒有重複評論。
變形蟲也將自動遞歸到子記錄,如果你讓他們
class Post < ActiveRecord::Base
has_many :comments
amoeba do
enable
end
end
class Comment < ActiveRecord::Base
belongs_to :post
has_many :ratings
amoeba do
enable
end
end
class Rating < ActiveRecord::Base
belongs_to :comment
end
你也可以用一些額外的數據前綴字段來表明其唯一
class Post < ActiveRecord::Base
has_many :comments
amoeba do
enable
prepend :title => "Copy of "
end
end
而且除了前面加上你可以還附加或運行給定字段上的正則表達式
享受! :)
您需要編寫自己的clone_with_associations方法,該方法需要經過一系列特定的關聯。理論上你可能寫一些通用的使用reflect_on_all_associations,但你需要在關聯的對象上做同樣的事情,這將不可避免地最終創建一個循環,產生無限量的記錄。
所以,只寫你自己的。像
#in Blerg
has_many :foos
has_many :bars #bars also have many chickens which we want to copy over as well
def clone_with_associations
new_blerg = self.dup
new_blerg.save
#simple association
new_blerg.foos = self.foos
#two-level association
self.bars.each do |bar|
new_bar = bar.clone
new_bar.save
new_bar.chickens = bar.chickens
new_blerg.bars << bar
end
new_blerg
end
東西現在你可以做
@new_blerg = Blerg.find(1).clone_with_associations
同樣,這個寶石似乎運作良好:https://github.com/moiristo/deep_cloneable,並且非常易於使用。
只是
gem ‘deep_cloneable’, ‘~> 1.4.0’
然後:
pirate.deep_clone :include => :mateys
哇這個寶石真的很棒。我不得不推出我自己的複製系統,它不能正常工作,但你的寶石工作得很好。 – Amala 2012-04-12 01:05:05
該示例中的.dup應該是「new_post = my_post.amoeba_dup」,如文檔中所定義的那樣? – kibaekr 2014-01-31 08:04:51
@kibaekr從README歷史記錄我發現「截至2012年12月11日,Amoeba不再覆蓋內置的ActiveRecord :: Base#dup'方法,而是實現了自己的方法,名爲'amoeba_dup' ...」 – Sam 2016-03-31 13:44:46