回滚模型 - 从动作变化

时间:2016-04-15 08:47:46

标签: ruby-on-rails ruby-on-rails-4 model rollback

我有动作,我将组分配给适用的成员。基本上,我只是从表单中的视图中获取电子邮件列表,然后我就可以抓住它了:

我想知道的是,如果我可以回滚已经进行的更改,如果说第二个成员不存在,或者已经有一个组,我该如何回滚这些?

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

我已经考虑过的是将v.save和@ group.save移动到最后,然后再创建params[:member].each....的循环,但这会浪费资源,根据需要,将find_by_email方法执行两次。

1 个答案:

答案 0 :(得分:2)

我建议将非控制器逻辑移到模型中并将其包装在ActiveRecord::Base.transaction

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

使用事务作为SQL语句的保护包装,以确保只有在所有操作一起成功时才会发生对数据库的更改。