2012-07-27 3 views
6

등록 양식이 있습니다.레일 3 : 롤백 (after_create)

사용자가 등록 할 때 앱은 enrollments 테이블과 users 테이블에 데이터를 저장합니다. (사용자 프로필이 변경 될 수 있기 때문에이 분리가 필요하지만 특정 등록에 대해 입력 한 데이터는 보관해야하므로 나중에 사용자가 성을 변경하더라도 등록 양식에 초기 정보가 있습니다.)

그래서 나는 ... 이런 식으로, 다음 after_create 전화를 가지고있는 enrollments 테이블에 데이터를 저장에 대해 생각했다

class Enrollment < ActiveRecord::Base 

    after_create :save_corresponding_user 

    def save_corresponding_user 
    user = User.new 
    user.full_name = self.user_full_name 
    user.email = self.user_email 
    user.mobile_phone = self.user_mobile_phone 
    user.save 
    end 
end 

문제는, 어떤 사용자를 절약 어떤 이유로 실패하는 경우. enrollments 테이블에서 방금 저장 한 데이터를 롤백하고 삭제하려면 어떻게해야합니까?

+0

사용자가 여러 번 등록 할 수 있습니까? 그렇지 않으면 사용자 테이블에 직접 추가 필드를 추가합니다. –

+0

사실, 실제로 보육원에 아이를 입양하고있는 부모/보호자입니다. 그래서 예, 부모는 자녀를 여러 번 등록 할 수 있습니다. – leonel

+0

나에게 그것은 after_create에 save_corresponding_user를 두는 것이 문제가 될 것 같습니다. 사용자가 다시 등록하면 어떻게됩니까? 당신은 그들을 위해 새로운 사용자 객체를 생성하고 싶지 않을 것이다. 또한 등록 테이블에 user_id 열이 없을 가능성이 있습니까? 위의 코드에서는이 값을 채울 수 없습니다. 그것이 나 였다면 오류가 발생했을 때 두 가지 모두 롤백을 처리하는 트랜잭션에서 등록 및 사용자 작성을 마무리합니다. –

답변

12

after_create는 현재 모델을 저장하는 트랜잭션의 일부입니다. 따라서 코드가 충돌하거나 after_create가 false를 반환하면 현재 트랜잭션을 롤백하고 enrollment 저장을 무효화해야합니다.

이를 시뮬레이션 할 경우, after_create이를 추가하고 모든 것이 예상대로 작동하는지 확인 :

으로 @anthonyalberto 언급
raise Exception.new("CRASH") 
+0

mongodb와 같은 비 트랜잭션 데이터베이스를 사용하는 경우 롤백이 발생하지 않습니다. –

+3

after_create가 false를 반환하면 트랜잭션이 롤백되지 않는 것으로 나타납니다 (예외적 인 경우 만 해당). 적어도 레일즈 4에서. – djburdick

+0

@djburdick 예외가 발생하면 트랜잭션은 기본적으로 롤백되어야합니다. 그래서 이것이 예상 된 행동입니다. 나는이 대답이 그 세부 사항에 대해 약간 틀린 것이라고 생각한다. – leishman

1

, after_create 이미 트랜잭션의 일부입니다. 트랜잭션을 정의하려면 당신이 컨트롤러에이 같은 것을 사용하는 것이 :

입니다
Enrollment.transaction do 
    @enrollment.save! 
end 

정말 당신이해야 할 모든 등록의 저장이 실패하거나 사용자의 저장이이 전체 트랜잭션을 롤백합니다 실패하는 경우. 자세한 정보는 다음과 같습니다. http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

7

false에서 after_create까지 아무 것도하지 않습니다.

전체 콜백 체인이 트랜잭션으로 래핑됩니다. before 콜백 메소드가 정확히 false를 반환하거나 예외를 발생시키는 경우 실행 체인이 중지되고 ROLLBACK이 실행됩니다. 콜백이 예외를 발생 시켜야만 콜백을 수행 할 수 있습니다.

또한, 당신이 raise ActiveRecord::Rollback해야합니다

콜백 체인이 중단 된 후 액티브 :: 롤백이 레일에 의해 다시 제기 될 것이다되지 않은 모든 예외입니다. ActiveRecord :: Rollback 이외의 예외를 발생 시키면 save 및 update_attributes (일반적으로 true 또는 false를 반환하려고 시도하는)와 같은 메서드를 기대하지 않는 코드가 중단되어 예외가 발생합니다.

http://guides.rubyonrails.org/active_record_callbacks.html#halting-execution

내가 이런 일을 수행 레일 3

after_create do 
    if condition 
    errors.add(:attr, 'Blah blah blah.') 
    raise ActiveRecord::Rollback 
    end 
end 

가 : http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#halting-execution