ActiveRecord의 find_or_create_by_*column*
을 사용하려고하는데 때때로 Postgres에서 모델을 찾지 못하는 오류를보고 어차피 삽입하려고합니다. 이 테이블을 고유하게 유지하는 것이 중요하므로 Postgres가 내가 그것에 대해 진지하다는 것을 알 수 있도록 :unique => true
속성을 마이그레이션에 추가했습니다.find_or_create 경합 조건
그리고는 실패 :
ActiveRecord::StatementInvalid: PGError: ERROR: duplicate key value violates unique constraint "index_marketo_leads_on_person_id" DETAIL: Key (person_id)=(9968932) already exists. : INSERT INTO "marketo_leads" ("mkt_person_id", "synced_at", "person_updated_at", "person_id") VALUES(NULL, NULL, '2011-05-06 12:57:02.447018', 9968932) RETURNING "id"
내가 그렇게 같은 모델을 가지고 :
두 번째 모델은 Marketo와 전자 메일 서버에 우리의 사용자 계정을 연결하고 기록을 유지하기 위해 사용되는class User < AR::Base
has_one :marketo_lead
before_save :update_marketo_lead
def update_marketo_lead
if marketo_lead
if (User.marketo_columns & self.changes.keys).any?
marketo_lead.touch(:person_updated_at)
end
elsif self.id
marketo_lead = MarketoLead.find_or_create_by_person_id(:person_updated_at => Time.now, :person_id => self.id)
end
end
end
class MarketoLead
belongs_to :user, :foreign_key => 'person_id'
end
마지막으로 사용자의 특정 필드가 수정되어 배치 된 백그라운드 작업에서 변경된 레코드를 푸시 할 수 있습니다.
update_marketo_lead
은 내가 상상할 수없는 일종의 경쟁 조건 외에도이 콜백에 대한 어떤 이유도 생각할 수 없습니다.
('사용자'사람 '에 기본 키를 공유하는 horribleness 무시하십시오) (사용 레일 2.3.11을, 포스트 그레스 9.0.3)
을 올려 보자, 나는 좋은 조언을 감사드립니다 StatementInvalid 오류를 복구하고 유한 재시도 루프를 추가하십시오. 나는'find_or_create' 호출과 같은 예외 처리를 추가했다. 건배! – nessur
내 응용 프로그램에서 모델.ave는 컨트롤러에서 트리거되므로 시작하기 쉽도록 포장하기가 쉽습니다. 사실 나는 save_with_retries (retry_count = 5)라는 메소드를이 모델이 필요로하는 모델에 추가했습니다. –
P.S. ActiveRecord (트랜잭션 문서에 따라)가 이미 저장하고 저장하기 때문에 user.save 주변의 Transaction을 제거했습니다! 내부 거래를 파괴하십시오. –