【问题标题】:Rails - console says 'rendered' but the redirect not happeningRails - 控制台说“渲染”,但重定向没有发生
【发布时间】:2017-06-19 22:03:08
【问题描述】:

我编写了一个服务模块,它发出一个 API 请求,返回带有错误的字符串或带有参数的散列,并将其包含在控制器中。

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 请求会中断操作(整个控制器操作 > 300 毫秒)。我应该怎么做才能解决这个问题?

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • arg 这个!这救了我,卡住了至少一个小时。 Form_with 需要 local:true 来重定向!
    【解决方案2】:

    这里的问题是您正在尝试渲染但没有通过返回来停止控制器操作的进度。

    考虑替换内联到操作的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
    

    让我知道这是否有帮助。

    【讨论】:

    • 好的,问题出在使用 Ajax 提交的表单上。 Rails 5 中新的form_with 默认有remote: true,所以为了响应html,你必须指定local: true
    猜你喜欢
    • 2022-11-18
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    相关资源
    最近更新 更多