Ответ 1
Вы должны клонировать каждое испытание и назначать их клонированному эксперименту:
@experiment_new = @experiment_old.clone
@experiment_old.trials.each do |trial|
@experiment_new.trials << trial.clone
end
Я хотел бы сделать глубокую копию объектов, включая все атрибуты.
Эксперимент_old имеет 10 испытаний. И я хочу скопировать все на эксперимент_new с 10 испытаниями. experiment_old также должна содержать 10 пробных данных.
Тем не менее, во всех случаях, которые я пробовал ниже, они копируют все хорошо, но у экспериментального_сообщества нет 10 пробных данных. Они просто появляются на эксперименте_new.
Каков наилучший способ сделать глубокую копию для этих случаев.
случай 1:
@experiment_new = Experiment.create(@experiment_old.attributes.merge(:trials => experiment_old.trails))
случай 2:
@experiment_new = Marshal.load(Marshal.dump(@experiment_old.trials))
случай 3:
@experiment_new = @experiment_old.clone
Вот модель:
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
Вы должны клонировать каждое испытание и назначать их клонированному эксперименту:
@experiment_new = @experiment_old.clone
@experiment_old.trials.each do |trial|
@experiment_new.trials << trial.clone
end
Вы можете наслаждаться драгоценным камнем Амебы для 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
каждый из этих различных параметров должен приводить к повторному связыванию нового сообщения с теми же тегами, что и старое сообщение, но без дублирования комментариев.
Amoeba также автоматически перезаписывает дочерние записи, если вы включите их
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
и в дополнение к prepend вы также можете добавить или запустить регулярное выражение в заданном поле
Наслаждайтесь!:)