Rails - 控制台说'呈现'但重定向没有发生

时间:2017-06-19 22:03:09

标签: ruby-on-rails performance api controller request

我编写了一个发出API请求的服务模块,返回带有错误的字符串或带参数的哈希值,并将其包含在Controller中。

def create
    @new_params = ApiRequest.create_login(params, customer_secret) #this returns either a string or hash
    request_error? #if it's a string, it should immediately render :new
    params[:login] = @new_params #substitutes the params from the form with the API response
    @login = current_user.logins.new(login_params).save
  end

以下是如何在不尝试保存的情况下重定向

def request_error?
    respond_to do |format|
      if @new_params.is_a? String
        @error = @new_params
        format.html { render :new, notice: @error }
      end
    end
end

问题是,在控制台中它说rendered :new(甚至redirected_to new_login_path - 如果我使用它而不是渲染)但页面甚至没有重新加载,只是什么都没发生。即使它应该早先使用render:new退出创建操作,它仍然会尝试保存@login并失败。
我的猜测是长API请求会中断操作(整个控制器操作的时间> 300ms)。我该怎么做才能解决这个问题?

2 个答案:

答案 0 :(得分:2)

它与控制器或请求无关,form_with默认情况下是用Ajax提交的,为了响应html,我必须指定local: true。之前的评论解决了早期退出控制器操作的问题。问题

答案 1 :(得分:1)

这里的问题是你试图通过返回来渲染但不能停止控制器动作的进度。

考虑将内联的request_error?方法替换为操作:

def create
  @new_params = ApiRequest.create_login(params, customer_secret) #this returns either a string or hash
  respond_to do |format|
    if @new_params.is_a? String
      @error = @new_params
      format.html { render :new, notice: @error }
    end
  end
  params[:login] = @new_params #substitutes the params from the form with the API response
  @login = current_user.logins.new(login_params).save
end

由于您在条件内呈现时没有返回,因此操作会继续,然后继续保存您的登录信息。

为避免这种情况,您应该在条件中进行渲染时返回。

def create
  @new_params = ApiRequest.create_login(params, customer_secret) #this returns either a string or hash
  respond_to do |format|
    if @new_params.is_a? String
      @error = @new_params
      format.html { render :new, notice: @error and return }
    end
  end
  params[:login] = @new_params #substitutes the params from the form with the API response
  @login = current_user.logins.new(login_params).save
end

请注意,如果您继续使用方法request_error?,就可以执行此操作,就像在该方法中返回一样,您将控制权传递回操作。相反,你需要返回一个布尔值,比如说,确定你是否已经渲染,如:

def request_error?
    respond_to do |format|
      if @new_params.is_a? String
        @error = @new_params
        format.html { render :new, notice: @error }
        return true
      else
        return false
      end
    end
end

然后,如果有请求错误,请尽早返回:

  def create
    @new_params = ApiRequest.create_login(params, customer_secret) #this returns either a string or hash
    return if request_error? 
    params[:login] = @new_params #substitutes the params from the form with the API response
    @login = current_user.logins.new(login_params).save
  end

让我知道这是否有帮助。