TL : DR : AR :: Base 저장 트랜잭션 내에 중복 조인 테이블 레코드를 삽입하면 (고유 제한 조건으로 인해) 저장이 실패하고 롤백되는 원인이됩니다. 복제 조인 테이블 레코드를 추가하지 않아도됩니다. 저장하지 않는 것이 좋지 않습니다.postgres 데이터베이스 오류로 인해 트랜잭션 재시작이 발생합니다.
class EventsSeries < ActiveRecord::Base
# UNIQUE KEY `index_events_series_on_event_id_and_series_id` (`event_id`,`series_id`)
belongs_to :event
belongs_to :series
end
class Series < ActiveRecord::Base
has_many :events_series
before_validation :add_new_event
private
def add_new_event
# boils down to something like this
EventSeries.new.tap do |es|
es.event_id = 1
es.series_id = 1
begin
es.save!
rescue ActiveRecord::RecordNotUnique
# Great it exists
# this isn't really a problem
# please move on
end
end
end
end
호출 : 나는 포스트 그레스에 MySQL의 응용 프로그램을 마이그레이션하고있어
은 ... 나는 DB 조인 테이블 레코드를 추가 mysql을-땅에서이 같은 패턴 무언가를 수행하는 데 사용 이런 식으로 :
Series.first.save
# should not blow up on duplicate join record, cause i don't care
그러나이 경우 포스트그레스가 폭발합니다. 중복 레코드를 삽입 원인은
http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
에 ... "예외 처리 및 롤백"섹션
는 기본적으로 트랜잭션을 #save 시작 (경고 참조), 그리고 :이 여기에 좋은 설명이다 # save의 트랜잭션을 무효화하는 데이터베이스 예외 (sadface)입니다.
포스트 그레스 랜드에서 사용할 수있는 더 좋은 패턴이 있습니까?
감사합니다.
편집 :
나는 단단히 '은 시리즈 내에서이 논리를 유지 패턴은 다음과 같습니다 ... 트랜잭션을 저장하는 것이 합리적 생각:
s = Series.new
s.new_event_id = 123 # this is just an attr_accessor
s.save # callbacks on Series know how to add the new event.
... 내 수 컨트롤러는 매우 작습니다.
SELECT ... 쉐어가 마음에 와서 그것이 이미 있는지 확인합니다. 가능한 중복 데이터에 대해 수행 한 작업은 각 INSERT를 개별 트랜잭션으로 만드는 것입니다. – freeone3000
맞다. 그렇지만 내 논리가 저장 호출의 내부에 멋지게 싸여 질 수는 없다. – jsharpe
ActiveRecord는 savepoint와 같은 PostgreSQL 서브 트랜잭션에 액세스 할 수있는 방법을 제공합니까? plpgsql의 http://www.postgresql.org/docs/current/interactive/sql-savepoint.html ... 또는 EXCEPTION 절? http://www.postgresql.org/docs/current/interactive/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING – kgrittn