在儿童方法中满足条件时中断控制器父动作

时间:2016-02-13 19:32:44

标签: ruby-on-rails error-handling controller

我在我的hotel_controller中有几个操作,我调用API来获取数据。我创建了不同的服务来保持我的API调用在控制器逻辑之外。对于每个API调用,我都有一些“常规响应错误”,例如unauthorizednot found。由于这些错误对于所有API调用都是通用的,我想在我的酒店控制器中创建一个私有方法来处理它们:

private
     def global_error_checking(response)
        if response.message == "Unauthorized"
          redirect_to unauthorized_path and return
        elsif response.message == "Not Found"
          redirect_to not_found_path and return
        else
        end
      end

然后在我需要的控制器的每个方法中,我会在检查特定错误之前调用global_error_checking方法。例如:

  def index
    service = Hotels::GetHotelListService.new( account_id: params[:account_id],
                                               user_email: session[:user_email],
                                               user_token: session[:user_token]
                                              )
    @response = service.call
    global_error_checking(@response)
    if @response["hotels"].blank?
      flash[:notice] = "You have not created any hotels yet !"
      redirect_to account_path(params[:account_id])
    else
      @hotels =  @response["hotels"]
      @account = @response["account"]
    end
  end

问题是在执行global_error_checking之后,即使满足global_error_checking的条件,控制器的操作也会继续并且不会停止。

1)如果满足global_error_checking内的条件,如何停止执行整个控制器方法? 2)有没有更好的方法来实现这一目标?

2 个答案:

答案 0 :(得分:1)

我不会将参数命名为#34;响应"因为控制器已经在使用它。

我注意到的另一件事是你正在访问这个" @ response"以不同的方式可能没问题,但看起来不对。在您的global_error_checking方法中,您使用点语法(response.message)访问它的属性,但是在您的控制器操作中,您可以像访问哈希那样访问它。同样,根据其数据类型,这可能没问题。

如果我是你,我会将其重构为:

class SomeController < ApplicationController

  def index
    @hotels = some_resource['hotels']
    @account = some_resource['account']
  end

  private
  def some_resource
    @_some_resource ||= begin
      service = Hotels::GetHotelListService.new({
        account_id: params[:account_id],
        user_email: session[:user_email],
        user_token: session[:user_token]
      })

      result = service.call

      if result['message'] == 'Unauthorized'
        redirect_to unauthorized_path and return
      elsif result['message'] == 'Not Found'
        redirect_to unauthorized_path and return
      else
        result
      end
    end
  end
end

答案 1 :(得分:0)

您可以使用return语句: 控制器中的return if global_error_checking 和私有方法中的case语句有一些更改:

private
  #returns true after redirecting if error message "Unauthorized" or "Not Found"
  def global_error_checking(response) 
    case response.message
    when "Unauthorized"
      redirect_to unauthorized_path and return true
    when "Not Found"
      redirect_to not_found_path and return true
    end
  end