Ruby on rails 如何简化Rails中对块的大型响应

Ruby on rails 如何简化Rails中对块的大型响应,ruby-on-rails,ruby,Ruby On Rails,Ruby,是否有人建议我如何减少对块的响应?我的JSON格式似乎占用了相当大的空间。控制器在大多数情况下使用HTML响应,但此特定方法通过Ajax调用,并使用JSON响应: def create # initial setup respond_to do |format| unless paid_cash == true || PayPalPayments::OrderValidator.call(order_id) format.json do render

是否有人建议我如何减少
块的响应?我的JSON格式似乎占用了相当大的空间。控制器在大多数情况下使用HTML响应,但此特定方法通过Ajax调用,并使用JSON响应:

def create
  # initial setup

  respond_to do |format|
    unless paid_cash == true || PayPalPayments::OrderValidator.call(order_id)
      format.json do
        render json: {
          status: :unhandled_error,
          message: 'Invalid order ID supplied?'
        }, status: 400
      end
    end

    if @submitted_application.save(context: :create)
      MembershipMailer.with(application: @submitted_application).signup_confirmation.deliver_later

      format.json do
        render json: {
          status: :created,
          modal: render_to_string(
            partial: 'membership_confirmation_modal.html.erb'
          )
        }
      end
    else
      format.json do
        render json: {
          status: :validation_errors,
          errors: @submitted_application.errors
        }, status: 400
      end
    end
  end
end
如果您正在执行大量JSON响应,比如构建JSON API,那么创建一个简化该模式的方法是有意义的。例如,创建如下方法:

def respond_json(content)
  status = content[:status]

  render(
    json: content,
    status: STATUS_CODE_REMAPPED[status] || status
  )
end
它与您建立的结构一起工作,并使用它生成正确的
render
调用。由于这只适用于以特定方式结构化的数据,因此它有助于在响应中加强一致性

这取决于将内部代码映射到Rails响应代码:

STATUS_CODE_REMAPPED = {
  created: :ok,
  unhandled_error: :bad_request,
  validation_errors: :bad_request
}
其中,使用有助于代码变得更易于解释

另一件需要注意的事情是,您的订单验证可以在执行操作之前提取到
处理程序中:

before_action :verify_order_id, only: [ :create ]

def verify_order_id
  return if paid_cash || PayPalPayments::OrderValidator.call(order_id)

  respond_json(
    status: :unhandled_error,
    message: 'Invalid order ID supplied?'
  )
end
其中,如果处理程序呈现某个内容,则当请求被视为已服务时,链停止

这大大减少了控制器操作中剩余的代码量:

def create
  @submitted_application.save!(context: :create)

  MembershipMailer.with(application: @submitted_application).signup_confirmation.deliver_later

  respond_json(
    status: :created,
    modal: render_to_string(
      partial: 'membership_confirmation_modal.html.erb'
    )
  )

rescue ActiveRecord::RecordInvalid
  respond_json(
    status: :validation_errors,
    errors: @submitted_application.errors
  )
end
我用了
保存使预期路径更简单,没有分支。如果/当发生错误时,您可以进入异常处理区域

考虑在动作之前添加一个
,以验证请求者是否需要JSON,并在那里处理它,而不是在控制器动作中一批又一批的
响应
调用


不要忘了
rescue\u from
,它可以解决常见问题,如无效的请求类型等。这还可以减少您必须执行的重复代码的数量。

在99.9%的情况下,
x==true
可以减少为
x
paid\u cash
是否可以改为其他真实值,如
'yes'
?我建议尝试将逻辑从复合
重写为
语句,除非
if/else
语句<代码>除非
使逻辑复杂化,因为它基本上是一个
而不是if
,然后是另一个
if/else
,而一连串的ifs已经够糟糕的了。