【问题标题】:Is there a way to wrap the response of all controller methods in a json object in application_controller.rb?有没有办法将所有控制器方法的响应包装在 application_controller.rb 的 json 对象中?
【发布时间】:2019-06-26 11:51:56
【问题描述】:

我需要在一个地方(base_controller.rb 继承自 application_controller.rb)编写一些代码,在返回之前将来自控制器的所有传出 json 响应包装在一个 json 对象中。

在我的 Rails (5.x.x) 应用程序中,有大约 100 个端点服务于不同类型的数据(json 对象、数组、数组数组等)。由于最近的要求,我必须将它们全部包装在一个父对象中。

以前的状态:

some_controller.rb

return_obj = { key: value }
render json: return_obj

预期状态:

some_controller.rb 将返回{ key: value },但这将被base_controller.rb 拦截,而base_controller.rb 又会返回类似{ payload: { key: value }, other_info: info } 的内容

【问题讨论】:

    标签: ruby-on-rails interceptor actioncontroller


    【解决方案1】:

    Option-1:我们的设置中有类似的东西,我们所做的是,我们在base_api_controller 文件中有一个名为render_response 的方法。看起来像:

      def render_response(render_params)
        # controller_name, action_name will give you controller and action which rendered the response.
        # so you can decide weather to process anything or just render
    
        render_params[:json] = { payload: render_params[:json] }
        render render_params
      end
    

    您的控制器操作将转换为:

    return_obj = { key: value }
    render_response json: return_obj
    

    就个人而言(显然)我喜欢第一种方法,因为它是明确的,并且查看控制器代码可以让我们了解我们正在进一步处理响应的信息。

    选项2: 如果你不喜欢用render_response替换render你可以关注this guide来设置一个机架中间件,这也是死的简单。但是如果您不想对某些特定的控制器操作进行任何更新,则必须对控制器进行检查。还要注意它是自动的,所以在没有人注意到的情况下(让我们看到对你的代码完全陌生的人)它会改变响应。我个人不太喜欢。

    【讨论】:

    • 如果我们在base_controller 中有一个名为handle_responseafter_action 方法并让handle_response 对正在呈现的响应进行更改怎么办?这样就无需将render 更改为render_response。虽然,我同意中间件更适合这个用例,但我只是想知道在 after_action 中这样做的局限性。
    • @AnujKhandelwal 我不认为这会是任何问题,我们在 render_reponse 方法中也做了一些其他明确的事情,我们希望事情更明确,更神奇,这就是我们的原因明确地这样做。我想这只是选择的问题。
    • 是的。这就说得通了。显式肯定比隐式好,尤其是在 Rails 的所有魔力中。
    猜你喜欢
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-08
    相关资源
    最近更新 更多