2011-01-14 3 views
19

ActiveRecord에 내장 된 upsert 기능이 있습니까? 나는 나 자신을 쓸 수 있음을 알고 있지만 분명히 그런 것이 이미 존재한다면 나는 원하지 않는다.Upsert in Rails ActiveRecord

답변

13

Model.find_or_initialize 가능성이 높습니다. 그것이 의미가있는 경우 save 또는 update_attributes으로 연결할 수 있습니다.

자세한 내용은 Rails Guides. 난 그냥이 라이브러리 가로 질러

+3

파스타의 대답에 대한 의견보기 – tybro0103

+1

위의 사람이 업서 트를 생성 했습니까? 레일 가이드는 새로운 객체가 아직 DB에 저장되지 않았 음을 나타내므로이 객체가 실제 DB 업 샘플인지 확인할 수 없습니다. 즉, 멀티 스레드 환경에서는 안정적으로 작동하지 않습니다. – stuckj

+2

이 솔루션은 동시성 문제가 있습니다. 다른 쓰레드가'find_or_initialize'와'save' 사이에 테이블을 갱신하면 실패합니다. –

3

도 Model.find_or_create된다 https://github.com/seamusabshere/upsert

나는 아직 테스트하지 않은,하지만 약속 같은데

I가 블로그 게시물을 작성했다
+6

이것은 업 서트를 수행하지 않습니다. 선택 (select)을하고 (선택적으로) 삽입을합니다. 단일 스레드 세계에서 동일한 효과를 얻지 만 멀티 스레드 세계에서는 실제 업서 트를 수행해야합니다. – tybro0103

-1

우리가 어떻게 이룰 수 있는지. 그것을 확인해주세요 here.

활성 레코드 확장자를 써야합니다. 이런 식으로 보일거야.

module ActiveRecordExtension 
    extend ActiveSupport::Concern 

    def self.upsert(attributes) 
    begin 
     create(attributes) 
    rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation => e 
     find_by_primary_key(attributes['primary_key']). 
     update(attributes) 
    end 
    end 
end 

ActiveRecord::Base.send(:include, ActiveRecordExtension) 
+3

특히이 오류가 발생할시기를 예측할 수있을 때 예상되는 논리 흐름을 유도하기 위해 오류를 사용하는 팬이 아닙니다. – kmanzana

+0

좋은 지적 @kmanzana. 나에게 너무 익살 스럽네. IMHO – olleh

0

IMO Upsert 메커니즘에는 각 모델에 대한 사용자 지정 구성이 필요합니다.

따라서 가장 좋은 해결책은 모델에 대한 맞춤 SQL 쿼리를 구현하는 것입니다.

insert into <table> (<field_1>, ..., <field_n>) 
    values (<field_1_value>, ..., <field_n_value>) 
on duplicate key update 
    field_x = field_x_value, 
    ... 
    field_z = field_z_value;