简体   繁体   English

如何在Rails中使用嵌套JSON编写case语句

[英]How to write a case statement with nested JSON in rails

I have an app that is integrated with the Easypost API (for shipping stuff, really cool). 我有一个与Easypost API集成的应用程序(用于运送东西,真的很酷)。 I'm using their tracking information webhooks to fire events in my app. 我正在使用他们的跟踪信息webhooks触发我的应用中的事件。 I'm using ruby case statements to accomplish this. 我正在使用ruby case语句来完成此任务。 Here's a link to Easypost's API doc: https://www.easypost.com/docs/api#webhooks 这是Easypost的API文档的链接: https ://www.easypost.com/docs/api#webhooks

I would like to match my case statement to the result.status key value in the JSON. 我想将我的case语句与JSON中的result.status键值进行匹配。 Initially I was using just the description, but I need it to be more specific. 最初,我只使用描述,但是我需要使其更加具体。 Take a look: 看一看:

{
"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",

Here's the code I was using 这是我正在使用的代码

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

Since the status key is nested one level in the JSON do I need to account for that in my webhook code? 由于状态密钥在JSON中嵌套了一层,因此我需要在Webhook代码中解决这个问题吗? Might it be case params[:status] or case params[:result :status]? 可能是case params[:status]还是case params[:result :status]?

Thanks 谢谢

UPDATE UPDATE

I now realize I want to use some more granular details of the EasyPost API. 现在,我意识到我想使用EasyPost API的一些更详细的细节。 I need to access the status within the array of Tracking Details: 我需要访问“跟踪详细信息”数组中的状态:

//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
      }

So I need to access result and then tracking_details and then status . 所以我需要访问result ,然后是tracking_details ,然后是status this case statement: case params[:result][:tracking_details][:status] gave me this error: 这个案例陈述: 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'

Seems like it's because I need to specify the element in this array tracking_details . 似乎是因为我需要在此数组中指定元素tracking_details Anyone know how to reference that? 有人知道如何引用吗? Thanks 谢谢

Probably case params[:result][:status] 可能是case params[:result][:status]

params[:result] returns a hash which contains, among other things, the "status" member that you can access with [:status] params[:result]返回一个散列,该散列除其他外还包含可以使用[:status]访问的"status"成员。

EDIT to answer UPDATE 编辑以回答更新

params[:result][:tracking_details] returns an array, so you could try any of the following: params[:result][:tracking_details]返回一个数组,因此您可以尝试以下任何一种方法:

To get the first element: 要获得第一个元素:

  • params[:result][:tracking_details][0][:status]
  • params[:result][:tracking_details].first[:status]

To get all the elements: 获取所有元素:

  • params[:result][:tracking_details].map{|x| x[:status]}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM