2016-04-15 14 views
1

私は、適用するメンバーにグループを割り当てる場所にアクションがあります。基本的には、私はちょうどフォームのビューから電子メールのリストを取得し、それをキャッチするアクションを持っています:アクションからのモデル変更のロールバック

私は、すでに行われている変更をロールバックすることができます、 2番目のメンバーが存在しない、またはグループがすでに存在する場合は、どうすればこれらをロールバックできますか?

def group_create 
    @group = Group.new 
    params[:member].each { |m| 
    v = Volunteer.find_by_email(m[1]) 
    raise "#{m[1]} doesn't exist" unless v.present? 
    raise "#{v.email} is already in a group" if v.group.present? 
    v.group = @group 
    v.save! 
    } 
    @group.save 
rescue => error 
    flash[:error] = "Error: #{error}" 
ensure 
    respond_to do |format| 
    unless flash[:error].present? 
     flash[:notice] = 'Group Application succeded.' 
     flash[:joined] = true 
     format.html { redirect_to apply_group_path } 
    else 
     flash.discard 
     format.html { render :group } 
    end 
    end 
end 

私はすでにについて考えた何、find_by_email-を行うために、最後までv.saveと@ group.saveを移動し、params[:member].each....の別のループを作るが、それはressourcesのかなり無駄になりましたがメソッドを必要に応じて2回繰り返します。

答えて

2

私はあなたの非コントローラロジックをモデルに移動し、ActiveRecord::Base.transactionでそれを包むお勧め:SQL文の周りに保護ラッパーとして

ActiveRecord::Base.transaction do 
    @group = Group.new 
    params[:member].each { |m| 
     v = Volunteer.find_by_email(m[1]) 
     raise "#{m[1]} doesn't exist" unless v.present? 
     raise "#{v.email} is already in a group" if v.group.present? 
     v.group = @group 
     v.save! 
    } 
    @group.save 
end 

使用取引すべてのアクションが一緒に成功した場合にのみ発生し、データベースに変更を確実にするために。

+0

だから、Group.assign_membersを作成すると、電子メールの配列、またはそれらの行に沿ったものがありますか? –

関連する問題