ruby-on-rails - 데이터베이스 - 루비 온 레일즈
activerecord 레코드를 복제하는 가장 쉬운 방법은 무엇입니까? (7)
나는 activerecord 레코드의 사본을 만들고 id 와 함께 프로세스의 단일 필드를 변경하려고합니다. 가장 간단한 방법은 무엇입니까?
나는 새로운 레코드를 생성 한 다음, 필드별로 데이터를 복사하는 각 필드를 반복 할 수 있다는 것을 알았지 만,이 작업을 쉽게 수행 할 수있는 방법이 있어야한다고 생각했습니다 ...
예 :
@newrecord=Record.copy(:id) *perhaps?*
ActiveRecord 3.2에 대한 Amoeba 보석 을 좋아할 수도 있습니다.
귀하의 경우에는 구성 DSL에서 사용할 수있는 nullify
, regex
또는 prefix
옵션을 사용하고 싶을 것입니다.
has_one
, has_many
및 has_and_belongs_to_many
연관, 필드 전처리 및 모델에 즉시 적용 할 수있는 매우 유연하고 강력한 구성 DSL의 쉽고 자동적 인 재귀 적 복제를 지원합니다.
아메바 문서 를 확인하십시오. 그러나 사용법은 매우 쉽습니다 ...
다만
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
또한 여러 필드에서 복사 할 필드를 제어 할 수 있습니다. 예를 들어 주석을 복제하지 않고 동일한 태그를 유지하려는 경우 다음과 같이 할 수 있습니다.
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
연관을 재귀 적으로 복사하는 것은 쉽습니다. 자식 모델에서도 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
구성 DSL에는 더 많은 옵션이 있으므로 설명서를 확인하십시오.
즐겨! :)
ID를 복사하지 않으려면 ActiveRecord::Base#dup 사용하십시오.
다음은 인스턴스 복제를 사용자 정의하고 관계 복제를 포함하는 #dup
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
참고 :이 메서드는 외부 보석을 필요로하지 않지만 #dup
메서드가 구현 된 최신 ActiveRecord 버전이 필요합니다.
복사본을 얻으려면 clone (또는 레일 3.1의 dup) 메소드를 사용하십시오.
# rails < 3.1
new_record = old_record.clone
#rails >= 3.1
new_record = old_record.dup
그런 다음 원하는 필드를 변경할 수 있습니다.
ActiveRecord는 내장 Object # clone 을 오버라이드하여 할당되지 않은 ID가있는 새로운 (DB에 저장되지 않은) 레코드를 제공합니다.
연결을 복사하지 않으므로 필요한 경우 수동으로 연결해야합니다.
요구 사항 및 프로그래밍 스타일에 따라 클래스의 새 메서드와 병합을 조합하여 사용할 수도 있습니다. 보다 간단한 예제가 없다면 일정한 날짜에 작업을 예약하고 다른 날짜로 작업을 복제하려고한다고 가정합니다. 작업의 실제 속성은 중요하지 않으므로 다음을 수행하십시오.
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로 변경하십시오.
평화.
일반적으로 속성을 복사하고 변경이 필요한 부분을 변경합니다.
new_user = User.new(old_user.attributes.merge(:login => "newlogin"))
acts_as_inheritable gem을 확인할 수도 있습니다.
Acts As Inheritable은 Rails / ActiveRecord 모델 용으로 특별히 제작 된 루비 보석으로, 자체 참조 협회 또는 상속 가능한 속성을 공유하는 부모를 가진 모델과 함께 사용하기위한 것입니다. 부모 모델과의 관계. "
모델에 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
inherit_relations
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">
희망이 당신을 도울 수 있습니다.