我.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