簡體   English   中英

如何簡化 Rails 中的大型響應塊

[英]How to simplify large respond_to blocks in Rails

有沒有人對我如何減少respond_to塊有什么建議? 看起來我的 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處理程序中:

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

我用過save! 在這里,預期的路徑要簡單得多,沒有分支。 如果/當發生錯誤,那么你可以去扎進異常處理區。

考慮添加一個before_action來驗證請求者想要 JSON 並在那里處理它,而不是在控制器操作中存根大量的respond_to調用。

不要忘記rescue_from ,它可以從常見問題(如無效請求類型等)中進行全面救援。 這還可以減少您必須執行的重復代碼量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM