Как написать оператор 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]}
Другие вопросы по тегам