Railsでレコードを.cloneしています...
new_blerg = Blerg.find(1).clone
このレコードには、関連付けのロードとロードがあり、それらの関連付けには関連付けさえあります。
レコードをディープコピーして複製する方法はありますか?そうすれば、それらすべての関連付けも複製されますか?
ActiveRecord 3.2の Amoeba gem をうまく利用できるかもしれません。
has_one
、has_many
、has_and_belongs_to_many
の関連付けの簡単で自動な再帰的な複製、フィールドの前処理、およびモデルとオンザフライの両方に適用できる非常に柔軟で強力な構成DSLをサポートしています。
Amoeba Documentation を確認してください。ただし、使用方法は非常に簡単です...
ただ
gem install amoeba
または追加
gem 'amoeba'
あなたのGemfileに
次に、amoebaブロックをモデルに追加し、通常どおり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メソッドを記述する必要があります。理論的にはcouldは、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
同様に、このgemはうまく機能しているようです: https://github.com/moiristo/deep_cloneable 、非常に使いやすいです。
ただ
gem ‘deep_cloneable’, ‘~> 1.4.0’
その後:
pirate.deep_clone :include => :mateys