[英]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.