2011-05-12 5 views

답변

24

당신은 액티브 3.2의 Amoeba gem에서 좋은 사용을받을 수 있습니다 할 수 있습니다.

has_one, has_manyhas_and_belongs_to_many 협회, 필드 전처리 및 모델에와 비행에 모두 적용 할 수있는 매우 유연하고 강력한 구성 DSL 쉽게 자동 순환 중복을 지원합니다.

다음을 추가

Amoeba Documentation을 확인해야하지만, 사용이 매우 쉽습니다 ...

단지

gem install amoeba 

또는 Gemfile에

gem '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 

또는 필드 유형을 인식 (그리고 복사 thusly 히) 독점 구문

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 

을 표시하고 추가 할 수 있습니다 자식 레코드에 재귀 적 추가하거나 주어진 필드에 정규식을 실행하십시오

즐기십시오! :)

+1

와우이 보석 정말 놀랍습니다. 나는 내 자신의 복제 시스템을 굴려야했는데 작동하지 않았지만 보석이 정말 잘 작동했습니다. – Amala

+3

예에서 .dup는 문서에 정의 된대로 "new_post = my_post.amoeba_dup"이어야합니까? – kibaekr

+5

@kibaekr에서 읽은 README 기록에서 "2012 년 12 월 11 일 현재, Amoeba는 내장 된'ActiveRecord :: Base # dup' 메소드를 오버라이드하지 않고'amoeba_dup'라는 자체 메서드를 대신 구현합니다 ..." – Sam

18

특정 나열된 연결을 통과하는 고유 한 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 
+20

당신이'new_blerg.foos = self.foos' 당신의 연결을 훔치는로 깨진 원래 개체를 얻을 수 있습니다. 그들도 복제해야합니다. – RocketR

+1

이것은 가장 좋은 답변입니다. 나의 겸허 한 의견에서,이 경우에 당신 자신을 굴리는 것은 보석을 사용하는 것보다 훨씬 깨끗하고, 쉽고, 덜 마법적입니다. – hellion

+0

RocketR - 좋은 지적입니다. 나는 .fo 관계가 "가지고 있고 많은 것에 속한다"라고 가정하고 있었다고 생각합니다. 그렇다면 괜찮을 것입니다.하지만 foo belongs_to blerg then yes이면 관련 foos가 변경됩니다. –

15

똑같이이 보석은 잘 작동하는 것 같습니다 : https://github.com/moiristo/deep_cloneable이며 사용하기가 쉽습니다.

그냥

gem ‘deep_cloneable’, ‘~> 1.4.0’

다음 :

pirate.deep_clone :include => :mateys

+3

찾았습니다. 'amoeba'보다 구현하기가 더 쉽다 - 모델에서 선언 할 필요가 없다. – benjineer

+1

그래, 이것은 ameoba보다 훨씬 덜 오버 헤드이며, 배울 선언이나 dsl이 없다. 나는 그것이 "railsy"라고 생각한다. 유연성도 견고합니다. 레일스는 이것을 AR 메서드로 추가해야합니다. – bwest87

+1

새로운 좋아하는 보석. –

관련 문제