我编写了一个发出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)。我该怎么做才能解决这个问题?
答案 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
让我知道这是否有帮助。