ActiveRecordのtransactionでrollbackさせる
今つくってるやつは諸事情でActiveLdap使ってLDAPでもユーザの管理してるんだけど、LDAPとRDBの整合性をとるって結構無茶な気がしてきた。というか無茶。
とりあえずLDAPの方にデータ登録失敗したら、RDBのデータもロールバックしなきゃいけないからtransaction使ってごにょごにょやってた。ActiveRecordのsave!はずっとvalidator無視してsaveしてしまうメソッドだと思ってたら全然違った。本読まないで勘でやってるとこうなる。今度からちゃんと読もう。
で、save!メソッドは本当はsaveが失敗したときにRecordNotSavedって例外を投げるものだった。transactionはブロックの中で例外が発生したらロールバックする仕様らしいから使わざる終えないっぽい。
最終的にすごく雑だけど↓みたいな感じのソースになった。
def regist begin @user = User.new(params[:user]) @ldap_user = LdapUser.new(params[:ldap_user]); User.transaction do @user.save! @ldap_user.save! end redirect_to :action => 'finish' rescue ActiveRecord::RecordNotSaved render :action => 'confirm' rescue ActiveRecord::RecordNotFound redirect_to :controller => 'login' end end
あんまり公表できないソースなので色々削ってます。