Как написать оператор case с вложенным JSON в rails
У меня есть приложение, которое интегрировано с Easypost API (для доставки вещей, действительно круто). Я использую их информацию для отслеживания событий в моем приложении. Я использую рубин case
заявления для достижения этой цели. Вот ссылка на документ API Easypost: https://www.easypost.com/docs/api
Я хотел бы сопоставить мой оператор case со значением ключа result.status в JSON. Изначально я использовал только описание, но мне нужно, чтобы оно было более конкретным. Взглянуть:
{
"id": "evt_qatAiJDM",
"object": "Event",
"created_at": "2014-11-19T10:51:54Z",
"updated_at": "2014-11-19T10:51:54Z",
"description": "tracker.updated",
"mode": "test",
"previous_attributes": {
"status": "unknown"
},
"pending_urls": [],
"completed_urls": [],
"result": {
"id": "trk_Txyy1vaM",
"object": "Tracker",
"mode": "test",
"tracking_code": "EZ4000000004",
"status": "delivered",
"created_at": "2014-11-18T10:51:54Z",
"updated_at": "2014-11-18T10:51:54Z",
"signed_by": "John Tester",
"weight": 17.6,
"est_delivery_date": "2014-08-27T00:00:00Z",
"shipment_id": null,
"carrier": "UPS",
Вот код, который я использовал
class HooksController < ApplicationController
# to bypass CSRF token authenticity error
skip_before_filter :verify_authenticity_token
def stripe
#using easypost now as the webhook event
case params[:description]
# From EasyPost API https://www.easypost.com/docs/api#webhooks:
# tracker.updated: Fired when the status for the scan form changes
when 'tracker.updated'
@shipments = Spree::Shipment.where(transferred: false, state: "shipped")
@shipments.each do |shipment|
item_total = 0
shipment.line_items.each do |item|
item_total += item.product.price * item.quantity
end
transfer = Stripe::Transfer.create(
# Take 10% for ourselves from the total cost
# of items per supplier(shipment)
:amount => (item_total * (100 - shipment.supplier.commission_percentage)).floor,
:currency => "usd",
:recipient => shipment.supplier.token
)
shipment.transferred = true
shipment.save!
end
end
end
end
Поскольку статусный ключ вложен на один уровень в JSON, мне нужно учитывать это в моем коде webhook? Может быть case params[:status]
или же case params[:result :status]?
Спасибо
ОБНОВИТЬ
Теперь я понимаю, что хочу использовать более детальные детали API EasyPost. Мне нужно получить доступ к статусу в массиве деталей отслеживания:
//Easypost API
{
"id": "evt_qatAiJDM",
"object": "Event",
"created_at": "2014-11-19T10:51:54Z",
"updated_at": "2014-11-19T10:51:54Z",
"description": "tracker.updated",
"mode": "test",
"previous_attributes": {
"status": "unknown"
},
"pending_urls": [],
"completed_urls": [],
"result": {
"id": "trk_Txyy1vaM",
"object": "Tracker",
"mode": "test",
"tracking_code": "EZ4000000004",
"status": "delivered",
"created_at": "2014-11-18T10:51:54Z",
"updated_at": "2014-11-18T10:51:54Z",
"signed_by": "John Tester",
"weight": 17.6,
"est_delivery_date": "2014-08-27T00:00:00Z",
"shipment_id": null,
"carrier": "UPS",
"tracking_details": [
{
"object": "TrackingDetail",
"message": "BILLING INFORMATION RECEIVED",
"status": "pre_transit",
"datetime": "2014-08-21T14:24:00Z",
"tracking_location": {
"object": "TrackingLocation",
"city": null,
"state": null,
"country": null,
"zip": null
}
Так что мне нужно получить доступ result
а потом tracking_details
а потом status
, это утверждение дела: case params[:result][:tracking_details][:status]
дал мне эту ошибку:
May 14 10:31:30 leemaeats app/web.1: TypeError (no implicit conversion of Symbol into Integer):
May 14 10:31:30 leemaeats app/web.1: app/controllers/hooks_controller.rb:28:in `[]'
May 14 10:31:30 leemaeats app/web.1: app/controllers/hooks_controller.rb:28:in `stripe'
Похоже, это потому, что мне нужно указать элемент в этом массиве tracking_details
, Кто-нибудь знает, как ссылаться на это? Спасибо
1 ответ
Наверное case params[:result][:status]
params[:result]
возвращает хеш, который содержит, помимо прочего, "status"
член, к которому вы можете получить доступ [:status]
РЕДАКТИРОВАТЬ, чтобы ответить ОБНОВЛЕНИЕ
params[:result][:tracking_details]
возвращает массив, поэтому вы можете попробовать любое из следующего:
Чтобы получить первый элемент:
params[:result][:tracking_details][0][:status]
params[:result][:tracking_details].first[:status]
Чтобы получить все элементы:
params[:result][:tracking_details].map{|x| x[:status]}