Render failing to render correct template in rescue_from ActiveRecord::Rollback method

心已入冬 提交于 2019-12-06 15:14:45

I think the intention is a bit clearer when wrapping the transaction in a begin/rescue block.

def create
  begin 
    ActiveRecord::Base.transaction do
      @user = User.new params[:user]
      unless @user.save
        raise ActiveRecord::Rollback
      end
      //More stuff
      ...
      @order = Order.new params[:order]
      ...
      unless @order.save
        raise ActiveRecord::Rollback
      end
    end
  rescue ActiveRecord::Rollback
    render action: "new" and return
  end
end

You need to return in the create method, otherwise it's execution will continue to the end of the method and Rails default render will occur (in this case it means attempting to find a create.___ template).

If you don't like the begin/rescue block you can just add an and return to the raise lines

raise ActiveRecord::Rollback and return

Above answer is correct but some modification is required for rendering action.

Do it like this:-

def create
    is_project_saved = false
    is_proposal_saved = false

    ActiveRecord::Base.transaction do
      is_project_saved = @project.save
      is_proposal_saved = @proposal.save
      if is_project_saved && is_proposal_saved
        # Do nothing
      else
        raise ActiveRecord::Rollback
      end
    end

    if is_project_saved && is_proposal_saved
      # You can add more nested conditions as per you need.
      flash[:notice] = "Proposal Created Successfully."
      redirect_to project_show_path(:job_id => @project.job_id)
    else
      render :new
    end
end

ActiveRecord::Rollback will not be caught by resque. So it needs to be done outside transaction block.

You can also use save_point using :requires_new => true in nested ActiveRecord::Base.transaction.

You need to raise the ActiveRecord::Rollback and manage the render/redirect as you desire. As @WasimKhan said, the ActiveRecord::Rollback will not be caught by rescue.

def create
  @user = User.new params[:user]
  ActiveRecord::Base.transaction do
    if @user.save
      @order = Order.new params[:order]
      if @order.save
        redirect_to :index
      else
        raise ActiveRecord::Rollback
      end
    else
      render :new
    end
  end
  render :new if @user.id.nil?
end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!