문제

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

새 레코드를 만든 다음 필드별로 데이터를 복사하면서 각 필드를 반복할 수 있다는 것을 깨달았습니다. 하지만 이 작업을 수행하는 더 쉬운 방법이 있어야 한다고 생각했습니다.

와 같은:

 @newrecord=Record.copy(:id)  *perhaps?*
도움이 되었습니까?

해결책

복사본을 얻으려면 clone(또는 Rails 3.1의 경우 dup) 방법을 사용하세요.

# rails < 3.1
new_record = old_record.clone

#rails >= 3.1
new_record = old_record.dup

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

ActiveRecord는 내장된 Object#clone을 재정의합니다. 할당되지 않은 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로 변경하세요.

평화.

당신은 또한 아메바 보석 액티브레코드 3.2용.

귀하의 경우에는 아마도 nullify, regex 또는 prefix 구성 DSL에서 사용할 수 있는 옵션입니다.

쉽고 자동적인 재귀적 복제를 지원합니다. has_one, has_many 그리고 has_and_belongs_to_many 모델과 즉석에서 모두 적용할 수 있는 연관, 필드 전처리 및 매우 유연하고 강력한 구성 DSL을 제공합니다.

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

단지

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

다양한 방법으로 복사할 필드를 제어할 수도 있습니다. 예를 들어 댓글이 중복되는 것을 방지하고 동일한 태그를 유지하려는 경우 다음과 같이 할 수 있습니다.

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에는 더 많은 옵션이 있으므로 설명서를 꼭 확인하세요.

즐기다!:)

사용 활성 레코드::베이스#dup 아이디를 복사하고 싶지 않다면

나는 일반적으로 속성을 복사하여 변경해야 할 사항을 변경합니다.

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

연관이 포함된 딥 카피가 필요한 경우 다음을 권장합니다. deep_cloneable 보석.

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

#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     

Rails 5에서는 이와 같이 간단하게 중복 객체나 레코드를 생성할 수 있습니다.

new_user = old_user.dup

당신은 또한 확인할 수 있습니다 act_as_inheritable 보석.

"상속 가능으로 작동(Acts As Inheritable)은 Rails/ActiveRecord 모델용으로 특별히 작성된 Ruby Gem입니다.와 함께 사용하도록 되어 있습니다. 자기 참조 연관, 또는 상속 가능한 속성을 공유하는 상위 모델이 있는 모델입니다.이렇게 하면 상위 모델로부터 모든 속성이나 관계를 상속받을 수 있습니다."

추가하여 acts_as_inheritable 모델에 대해 다음 방법에 액세스할 수 있습니다.

상속_속성

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">

이것이 당신을 도울 수 있기를 바랍니다.

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

문서 예제에 따라 사용자 모델의 경우:

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

다음은 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

메모:이 방법에는 외부 gem이 필요하지 않지만 최신 ActiveRecord 버전이 필요합니다. #dup 구현된 방법

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top