programing

활성 레코드를 복제하는 가장 쉬운 방법은 무엇입니까?

newsource 2023. 6. 4. 10:33

활성 레코드를 복제하는 가장 쉬운 방법은 무엇입니까?

프로세스에서 (ID 외에) 단일 필드를 변경하는 ActiveRecord 개체의 복사본을 만들고 싶습니다.이를 달성하는 가장 간단한 방법은 무엇입니까?

저는 새로운 레코드를 만들고 각 필드에 데이터를 복사하는 작업을 반복할 수 있다는 것을 깨달았습니다. 하지만 더 쉬운 방법이 있을 거라고 생각했습니다.

아마도 다음과 같은 것이 있을 것입니다.

 new_record = Record.copy(:id)

복사본을 가져오려면 dup(또는 clone for < rails 3.1+) 방법을 사용합니다.

#rails >= 3.1
new_record = old_record.dup

# rails < 3.1
new_record = old_record.clone

그런 다음 원하는 필드를 변경할 수 있습니다.

ActiveRecord는 기본 제공 Object#클론을 재정의하여 할당되지 않은 ID의 새 레코드를 DB에 저장하지 않은 상태로 제공합니다.
연결을 복사하지 않으므로 필요한 경우 수동으로 이 작업을 수행해야 합니다.

Rails 3.1 클론은 얕은 복사본입니다. 대신 dup을 사용하십시오...

필요한 사항과 프로그래밍 스타일에 따라 클래스의 새 메서드를 조합하여 사용하고 병합할 수도 있습니다.나은 단순한 예제가 없는 경우 특정 날짜에 예약된 작업이 있고 이를 다른 날짜로 복제하려고 합니다.작업의 실제 속성은 중요하지 않으므로 다음과 같습니다.

old_task = Task.find(task_id)new_task = Task.new(old_task.attributes.merge({:scheduled_on => some_new_date})

를 사용하여 새 작업을 생성합니다.:id => nil,:scheduled_on => some_new_date기타 모든 속성은 원래 작업과 동일합니다.Task.new를 사용하면 명시적으로 save를 호출해야 하므로 자동으로 저장하려면 Task.new를 Task.create로 변경합니다.

평화.

ActiveRecord 3.2용 아메바 보석도 좋습니다.

당신의 경우, 당신은 아마도 다음을 이용하고 싶을 것입니다.nullify,regex또는prefix구성 DSL에서 사용할 수 있는 옵션입니다.

의 쉽고 자동적인 재귀 복제를 지원합니다.has_one,has_many그리고.has_and_belongs_to_many모델과 현장 모두에 적용할 수 있는 매우 유연하고 강력한 구성 DSL을 제공합니다.

아메바 설명서를 꼭 확인해 보세요. 하지만 사용법은 꽤 쉽습니다.

그저.

gem install amoeba

또는 추가

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

또한 여러 가지 방법으로 복사할 필드를 제어할 수 있지만, 예를 들어 주석이 중복되지 않도록 하고 동일한 태그를 유지하려면 다음과 같은 작업을 수행할 수 있습니다.

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
    include_field :tags
    prepend :title => "Copy of "
    append :contents => " (copied version)"
    regex :contents => {:replace => /dog/, :with => "cat"}
  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

구성 DSL에는 더 많은 옵션이 있으므로 설명서를 확인하십시오.

맛있게 드세요! :)

활성 레코드 사용:: id를 복사하지 않으려면 base#up

저는 보통 속성을 복사하여 변경해야 할 사항을 변경합니다.

new_user = User.new(old_user.attributes.merge(:login => "newlogin"))

연결이 포함된 딥 복사본이 필요한 경우 deep_clonable gem을 추천합니다.

Rails 5에서는 다음과 같은 복제 개체 또는 기록을 만들 수 있습니다.

new_user = old_user.dup

은 ActiveRecord 파일의 ActiveRecord 파일을 입니다.#dup인스턴스 복제를 사용자 정의하고 관계 복제도 포함하는 방법:

class Offer < ApplicationRecord
  has_many :offer_items

  def dup
    super.tap do |new_offer|

      # change title of the new instance
      new_offer.title = "Copy of #{@offer.title}"

      # duplicate offer_items as well
      self.offer_items.each { |offer_item| new_offer.offer_items << offer_item.dup }
    end
  end
end

참고: 이 방법은 외부 보석을 필요로 하지 않지만 새로운 ActiveRecord 버전이 필요합니다.#dup된 방법

쉬운 방법은 다음과 같습니다.

#your rails >= 3.1 (i was done it with Rails 5.0.0.1)
  o = Model.find(id)
 # (Range).each do |item|
 (1..109).each do |item|
   new_record = o.dup
   new_record.save
 end

또는

# if your rails < 3.1
 o = Model.find(id)
 (1..109).each do |item|
   new_record = o.clone
   new_record.save
 end     

acts_as_inheritable gem을 확인할 수도 있습니다.

"상속할 수 있는 대로 행동하라"는 Rails/ActiveRecord 모델을 위해 특별히 작성된 루비 보석입니다.자체 참조 연결 또는 상속 가능한 특성을 공유하는 상위 모델과 함께 사용됩니다.이렇게 하면 상위 모델에서 모든 속성 또는 관계를 상속할 수 있습니다."

추가함으로써acts_as_inheritable모델에 대해 다음 방법에 액세스할 수 있습니다.

inherit_속성

class Person < ActiveRecord::Base

  acts_as_inheritable attributes: %w(favorite_color last_name soccer_team)

  # Associations
  belongs_to  :parent, class_name: 'Person'
  has_many    :children, class_name: 'Person', foreign_key: :parent_id
end

parent = Person.create(last_name: 'Arango', soccer_team: 'Verdolaga', favorite_color:'Green')

son = Person.create(parent: parent)
son.inherit_attributes
son.last_name # => Arango
son.soccer_team # => Verdolaga
son.favorite_color # => Green

상속_관계

class Person < ActiveRecord::Base

  acts_as_inheritable associations: %w(pet)

  # Associations
  has_one     :pet
end

parent = Person.create(last_name: 'Arango')
parent_pet = Pet.create(person: parent, name: 'Mango', breed:'Golden Retriver')
parent_pet.inspect #=> #<Pet id: 1, person_id: 1, name: "Mango", breed: "Golden Retriver">

son = Person.create(parent: parent)
son.inherit_relations
son.pet.inspect # => #<Pet id: 2, person_id: 2, name: "Mango", breed: "Golden Retriver">

이것이 당신에게 도움이 되길 바랍니다.

모델을 복제할 때 논리가 더 많을 수 있으므로 필요한 모든 논리를 처리하는 새로운 클래스를 만드는 것이 좋습니다.그것을 완화하기 위해, 도움이 될 수 있는 보석이 있습니다: 광대.

설명서의 예에 따라 사용자 모델의 경우:

class User < ActiveRecord::Base
  # create_table :users do |t|
  #  t.string :login
  #  t.string :email
  #  t.timestamps null: false
  # end

  has_one :profile
  has_many :posts
end

클론 클래스를 만듭니다.

class UserCloner < Clowne::Cloner
  adapter :active_record

  include_association :profile, clone_with: SpecialProfileCloner
  include_association :posts

  nullify :login

  # params here is an arbitrary Hash passed into cloner
  finalize do |_source, record, params|
    record.email = params[:email]
  end
end

class SpecialProfileCloner < Clowne::Cloner
  adapter :active_record

  nullify :name
end

그런 다음 사용합니다.

user = User.last
#=> <#User(login: 'clown', email: 'clown@circus.example.com')>

cloned = UserCloner.call(user, email: 'fake@example.com')
cloned.persisted?
# => false

cloned.save!
cloned.login
# => nil
cloned.email
# => "fake@example.com"

# associations:
cloned.posts.count == user.posts.count
# => true
cloned.profile.name
# => nil

예를 들어 프로젝트에서 복사했지만, 이를 통해 달성할 수 있는 목표에 대한 명확한 비전을 얻을 수 있습니다.

빠르고 간단한 기록은 다음과 같습니다.

Model.new(Model.last.attributes.reject {|k,_v| k.to_s == 'id'}

레일트테를 .dup방법:

new_record = old_record.dup.save

언급URL : https://stackoverflow.com/questions/60033/what-is-the-easiest-way-to-duplicate-an-activerecord-record