首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby on Rails对象及其属性的深度复制/深度克隆

Ruby on Rails对象及其属性的深度复制/深度克隆
EN

Stack Overflow用户
提问于 2011-06-17 04:34:56
回答 2查看 19.1K关注 0票数 18

我想在对象上做一个深度拷贝,包括所有属性。

experiment_old有10个试验。我想把10个试验的所有东西都复制到experiment_new上。experiment_old也应该保留这10个试验信息。

然而,我在下面尝试的所有案例都很好地复制了所有内容,但experiment_old没有10个试验信息。他们就会出现在experiment_new上。

对于这些情况,执行深度复制的最佳方式是什么?

案例1:

代码语言:javascript
复制
@experiment_new = Experiment.create(@experiment_old.attributes.merge(:trials => experiment_old.trails))

案例2:

代码语言:javascript
复制
@experiment_new = Marshal.load(Marshal.dump(@experiment_old.trials))

案例3:

代码语言:javascript
复制
@experiment_new = @experiment_old.clone

以下是模型:

代码语言:javascript
复制
class Experiment < ActiveRecord::Base
  belongs_to :experimenter
  has_many :trials
  has_many :participants
end


class Trial < ActiveRecord::Base
  belongs_to :experiment
  belongs_to :datum
  belongs_to :condition
  has_one :result_trial
end
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-06-17 07:35:18

您应该克隆每个试验,并将它们分配给克隆的实验:

代码语言:javascript
复制
@experiment_new = @experiment_old.clone
@experiment_old.trials.each do |trial|
  @experiment_new.trials << trial.clone
end
票数 24
EN

Stack Overflow用户

发布于 2012-02-29 00:33:50

你可能会喜欢ActiveRecord 3.2版的Amoeba gem

它支持has_onehas_manyhas_and_belongs_to_many关联的简单和自动递归复制,字段预处理和一个高度灵活和强大的配置DSL,可以应用于模型和动态。

请务必查看Amoeba Documentation,但使用起来非常简单……

只是

代码语言:javascript
复制
gem install amoeba

或添加

代码语言:javascript
复制
gem 'amoeba'

到你的Gemfile

然后将阿米巴代码块添加到您的模型中,并照常运行dup方法

代码语言:javascript
复制
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禁用各种记录的复制,您可以在文档中了解到这一点,但例如,如果您想保留标记,而不是注释,您可以这样做:

代码语言:javascript
复制
class Post < ActiveRecord::Base
  has_many :comments
  has_and_belongs_to_many :tags

  amoeba do
    include_field :comments
  end
end

或使用独占语法

代码语言:javascript
复制
class Post < ActiveRecord::Base
  has_many :comments
  has_and_belongs_to_many :tags

  amoeba do
    exclude_field :comments
  end
end

或通过指定要识别的字段类型(并因此复制)

代码语言:javascript
复制
class Post < ActiveRecord::Base
  has_many :comments
  has_and_belongs_to_many :tags

  amoeba do
    recognize :has_and_belongs_to_many
  end
end

这些不同的选项中的每一个都应该导致将新帖子与旧帖子的相同标签重新关联,但不会复制评论。

如果启用阿米巴,它还会自动递归到子记录

代码语言:javascript
复制
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

您还可以在字段前添加一些额外的数据以表示唯一性

代码语言:javascript
复制
class Post < ActiveRecord::Base
  has_many :comments

  amoeba do
    enable
    prepend :title => "Copy of "
  end
end

除了prepend之外,您还可以附加到给定字段或在给定字段上运行regex

尽情享受!:)

票数 26
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6378257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档