不知道怎么清理&使用我看似很难解析的JSON响应

时间:2016-07-14 02:01:05

标签: ruby-on-rails arrays ruby json parsing

Rails 4.2开发环境

我有一个控制器Searches

def index
  @search_term = params[:s] || 'shoes'
  @listings = Class_name.for(@search_term)
end

控制器用于Class_name类对象的模型&对象使用的for方法:

class Class_name
include HTTParty

base_uri 'http://svcs.ebay.com/services/search/FindingService/v1?SERVICE-NAME=FindingService&OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.13.0&SECURITY-APPNAME=xxxx&RESPONSE-DATA-FORMAT=JSON&REST-PAYLOAD&GLOBAL-ID=EBAY-US&paginationInput.entriesPerPage=25&paginationInput.pageNumber=1'
format :json

  def self.for term
    get("", query: { keywords: term})["findItemsByKeywordsResponse"]
  end

end

最后一个视图 - 我创建一个表来显示来自eBay API的解析响应。

<table border="1">
<tr>
    <th>Image</th>
    <th>Name</th>
</tr>
<% @listings.each do |product| %>
<tr>
    <td><%= image_tag(product["searchResult"][0]["item"][0]["galleryURL"])%></td>
    <td><%= product["searchResult"][0]["item"].sample(25) %></td>
</tr>
    <% end %>
</table> 

我的问题是模型和视图。

对于模型,我尝试添加一个default_params HTTParty方法 - 让我的base_uri没有那么长且更容易管理 - 但是当我写的时候:

default_params SERVICE-NAME: "FindingService", OPERATION-NAME: "#{operation}" ,etc ,etc

它会给我错误基本上说符号不能是常量“SERVICE-NAME”,但是api的参数必须是/应该是大写。< / p>

为什么常量不能被认为是具有指定值的哈希/符号?我猜是因为他们预计会按惯例预先分配一个值?

我如何以比现在更安全的方式分配这些值 - 不能将它们用作符号?的 - &GT;&GT;&GT;由Starbelly回答。

此外,考虑到人们是否遵循重定向,隐藏我的App ID是否有任何优点 - 无论如何都不会在URL中显示App ID?如果没有,他们不需要它来遵循重定向吗?

联盟会员ID呢?我肯定需要将联盟会员ID保留在将某人重定向到流量链接以获得信用的URL中。

在视图问题上: 这是真正给我带来麻烦的部分。

因此,在模型代码中,您会看到self.for(term)方法,它会将您提供的参数用于查询搜索所需的关键字参数。它会生成一个JSON格式的值为findItemsByKeywordsResponse的值,我想访问它。

寻找椅子, 开头的代码如下所示:

   {
findItemsByKeywordsResponse: [
{
ack: [
"Success"
],
version: [
"1.13.0"
],
timestamp: [
"2016-07-11T01:33:40.002Z"
],
searchResult: [
{
@count: "25",
item: [
{
    itemId: [
        "351198621254"
            ],
    title: [
        "Black PU Leather High Back Office Chair Executive Task Ergonomic Computer Desk"
           ],
    globalId: [
        "EBAY-US"
           ],
    subtitle: [
        "Ship from IN & CA ! Delivery in 1-3 Days US 48 States !"
              ],
    primaryCategory: [
        {
        categoryId: [
            "61677"
                    ],
        categoryName: [
            "Chairs"
                      ]
        }
                     ],
    secondaryCategory: [
        {
        categoryId: [
            "54235"
                    ],
        categoryName: [
            "Chairs"
                      ]
        }
                      ],
    galleryURL: [
        "http://thumbs3.ebaystatic.com/m/mBdjVHSC7hWaSBl-4Ku69aA/140.jpg"
                ],
     viewItemURL: [
        "http://www.ebay.com/itm/Black-PU-Leather-High-Back-Office-Chair-Executive-Task-Ergonomic-Computer-Desk-/351198621254"
                  ],
    paymentMethod: [
        "PayPal"
                   ],
    autoPay: [
        "true"
             ],
    postalCode: [
        "91748"
                ],
    location: [
        "Rowland Heights,CA,USA"
              ],
    country: [
        "US"
             ],
    shippingInfo: [
        {
            shippingServiceCost: [
        {
            @currencyId: "USD",
                __value__: "0.0"
        }
                                 ],
    shippingType: [
        "Free"
                  ],
    shipToLocations: [
            "US"
                     ],
    expeditedShipping: [
        "true"
                       ],
    oneDayShippingAvailable: [
        "false"
                             ],
    handlingTime: [
        "0"
                  ]
        }
                  ],
    sellingStatus: [
        {
        currentPrice: [
        {
        @currencyId: "USD",
            __value__: "99.99"
        }
                      ],
    convertedCurrentPrice: [
        {
        @currencyId: "USD",
        __value__: "99.99"
        }
                           ],
    sellingState: [
        "Active"
                  ],
    timeLeft: [
        "P26DT23H9M53S"
              ]
        }
                ],
    listingInfo: [
        {
        bestOfferEnabled: [
            "false"
                 ],
        buyItNowAvailable: [
            "false"
                           ],
        startTime: [
            "2014-10-17T00:43:32.000Z"
                  ],
    endTime: [
        "2016-08-07T00:43:32.000Z"
             ],
    listingType: [
        "FixedPrice"
                 ],
    gift: [
        "false"
          ]
        }
             ],
    returnsAccepted: [
        "true"
                     ],
    condition: [
        {
        conditionId: [
            "1000"
                     ],
        conditionDisplayName: [
            "New"
                              ]
        }
               ],
    isMultiVariationListing: [
        "false"
                             ],
    discountPriceInfo: [
        {
        originalRetailPrice: [
        {
        @currencyId: "USD",
            __value__: "209.99"
        }
                            ],
        pricingTreatment: [
            "STP"
                          ],
        soldOnEbay: [
            "false"
                    ],
        soldOffEbay: [
            "false"
                     ]
        }
                     ],
    topRatedListing: [
        "true"
                     ]
        },

在上面代码的最后一个逗号之后,它重复下一个项目数组。 [“item”] [1]在JSON中具有与上述相同的属性。

还有一些代码,但所有嵌套都与此部分相似。 到目前为止,此代码仅针对一个单独的项目&amp;如模型中的base_uri params&amp;查看,每个页面都被分为25个项目&amp;正在抽样25件物品进行展示。

我意识到要单独访问此信息,您必须访问项目数组["item"][0], ["item"][1],等以获取["title"]等信息 对于每种产品。

我甚至使用上述方法测试了我的代码,并且这样做(product["searchResult"][0]["item"][0]["title"])我可以在每个产品的基础上将标题值放在我的表中 - 但它没有格式化并正确显示。 实际值显示在数组中:

["Black PU Leather High Back Office Chair Executive Task Ergonomic Computer Desk"]

使用数值块和引号围绕值和所有内容 - 在我的视图文件中编码的表内呈现。

如何从数组/哈希中提取“true”值? - 摆脱数组块代码和引号

另外 - 再次 - 如模型文件的base_uri代码中所示,在获取请求时,列表会自动分页,每页25个产品。

了解这个&amp;预先定义此内容,如何迭代并访问所有25个["searchResult"][0]["item"][1..25] title值的值&amp; galleryURL值? &安培;再来一次。在摆脱每个值周围的[ ]""时。

我现在使用的代码,对25个["item"]数组值进行采样,基本上只是渲染我之前从findItemsKeywordsResponse JSON表中发布的确切代码,而我一直在尝试想出这一切。

对此的帮助将非常感激。

另外 - 即使对上面的25个["item"]数组值进行采样,它也不会迭代25中的任何一个。它会在一行中渲染所有25个样本。

1 个答案:

答案 0 :(得分:1)

回答你的第一个问题:

使用哈希火箭:default_params "SERVICE-NAME" => "FindingService", "OPERATION-NAME" => "#{operation}"

至于JSON,您可以发布完整的回复吗?它似乎在最后被切断了。

回答关于迭代项目等的问题。有多种方法可以做到这一点,这里有一个:

items = {
      item: [{
        itemId: [
          '351198621254',
        ],
    title: [
      'Black PU Leather High Back Office Chair Executive Task Ergonomic Computer Desk',
    ],
  },
    {
    itemId: [
      '551198621254',
    ],
    title: [
      'Blue PU Leather High Back Office Chair Executive Task Ergonomic Computer Desk',
    ]
    }
  ]
}

def parse_response_item_list(res)
  items = []
  res[:item].each do |item|
    parse_response_item(item) do |parsed|
      items << parsed
    end
  end
  items
end

def parse_response_item(res)
  tidy_result = {}
  if res.is_a? Hash
    res.each_pair do |key,val|
      if val.is_a? String
        tidy_result[key] = val
      else
        parse_response_item(val) do |string|
          tidy_result[key] = string
        end
      end
    end
    yield tidy_result
  elsif res.is_a? Array
    res.each do |e|
      parse_response_item(e) { |r| yield r }
    end
  elsif res.is_a? String
    yield res
  end
  tidy_result
end

result = parse_response_item_list(items)
p result
[
  { 
    :itemId=>"351198621254", 
    :title=>"Black PU Leather High Back Office Chair Executive Task Ergonomic Computer Desk"
  }, 
  { 
    :itemId=>"551198621254", 
    :title=>"Blue PU Leather High Back Office Chair Executive Task Ergonomic Computer Desk"
  }
]

另外,请注意,您在上面发布的响应不是json,它看起来像是ruby数组的数据转储。