【问题标题】:How do I group objects returned by a REST API based on a value inside that object?如何根据对象内部的值对 REST API 返回的对象进行分组?
【发布时间】:2017-06-23 16:30:12
【问题描述】:

我对 ruby​​/rails 很陌生,所以请耐心等待。

我正在尝试获取 JIRA rest API 返回的结果并将它们呈现在视图中。我可以使用jira-ruby gem 轻松做到这一点。我遇到的问题是按 API 返回的对象内的特定对象对结果进行分组(在本例中,是“问题”对象内的“组件”字段对象)。我试图为此使用 group_by 和 chunk 但我基本上得到了我想要的相反。两种方法都返回相同的结果。

在我的控制器中,我有:

@issues = @jira_client.Issue.all

在我看来,我有:

<% @issues.chunk {|issue_comp| issue_comp.fields["components"]}.each do |comps, issues| %>
    <h2>
        <% comps.each do |comp| %>
            <%= comp["name"] %>
        <% end %>
    </h2>
    <ul>
        <% issues.each do |issue| %>
            <li><p><%= link_to issue.key, "http://localhost:2990/jira/browse/#{issue.key}" %> - <%= issue.summary %></p></li>
        <% end %>
    </ul>
<% end %>

我最终得到的是:

CompA CompB

  • 问题A

CompC CompD

  • 问题B

CompA CompC CompD

  • 问题C

等等

我想要的是:

CompA

  • 问题A
  • 问题C

补偿

  • 问题A

补偿

  • 问题B
  • 问题C

补偿

  • 问题B
  • 问题C

API 返回的对象是一个非常复杂的对象(即散列内部数组中的巨大散列数组)。所以,我必须深入挖掘才能获得组件名称。

我觉得这不应该像看起来那么复杂,但我有一个可怕的习惯,就是让事情变得比实际需要的更复杂。我在这里做错了什么?

编辑:我创建了上面调用返回的完整转储的要点。注意“组件”数组:

jira-ruby gem dump for all issues

【问题讨论】:

  • 我们需要样本输入和所需的输出。
  • @Anthony 我添加了示例输入。除非我遗漏了什么,否则所需的输出已经存在?基本上,我想在我的视图中按组件名称对组件的所有常见问题进行分组。
  • 我在 JSON 查看器中查看了您的示例数据,但不足以证明您遇到的问题。您能否包含会产生您想要的结果的数据,以便我们可以看到它的原始形式?当然,请务必混淆您的私人数据。
  • @DanLaffan 对不起,你是对的。我创建了完整转储的要点。我清理了它以获取私人数据,但实际上没有,因为它们都在开发环境中。

标签: ruby-on-rails ruby grouping jira-rest-api


【解决方案1】:

我查看了您从 Jira 返回的数据。在我看来是这样的:

  • 有一个外部 Jira 问题数组。
  • 每个问题都有一个“attrs”哈希
  • 每个“attrs”哈希都包含组件。

如果这种理解是正确的,我认为您正在尝试反转该结构,以便您可以获得完整的组件列表,然后遍历每个组件,并显示属于该组件的问题。

如果这种理解是正确的,那么您有两个基本选择:

  • 检查您是否可以向 Jira 询问该信息(这样您就不必自己生成),或者
  • 构建您自己的数据结构(在您喜欢的本地数据库中的内存中):

一些用于在内存中构建有用结构的示例代码:

# in a controller, model, or service class (as you wish)
@components = {}
@jira_issues_array.each do |jira_issue| # from your API call
  jira_issues[:components].each do |jira_component|
    @components[jira_component[:key]] ||= { name: jira_component[:name], issue_keys: [] }
    @components[jira_component[:key]][:issue_keys] << jira_issue[:key]
  end
end

在您看来,您可以像这样迭代@components:

# some html.erb file:
<h1>Components and Issues</h1>

<ul>
  <% @components.keys.each do |component_key, component| %>
    <li><%= component[:name] %>
      <ul> <!-- nested -->
        <% component[:issue_keys].each do |issue_key| %>
          <%= @jira_issues_array.find { |issue| issue[:key] == issue_key }[:name] %>
        <% end %>
      </ul>
    </li>
  <% end %>
</ul>

注意:就像一个典型的懒惰程序员一样,我没有尝试过这个,但它真的是为了展示你可以如何去做。例如,每个问题的名称都嵌入在 attrs 部分中,因此您需要稍微挖掘一下。

最后,如果有人觉得这很有用,我会使用this to analyse and reformat JSON

HTH - 如有任何问题或问题,请发表评论。

【讨论】:

  • 谢谢丹!我只做了几处修改就将它放到了我的环境中,但由于#<:resource::issue:0x007fcb2620d9d0> 的未定义方法“[]”而破坏了我的视图。这引出了一个问题,我应该将来自 API 的响应存储在我的数据库中吗?我最初认为这不是正确的做法,因为这似乎是不必要的步骤。然而,考虑到对返回数据采取行动的复杂性,也许是这样?
  • 您的回答为我提供了足够的线索来构建解决方案。作为记录,我目前没有将其存储在我的数据库中,因此我必须调整我的解决方案以使用在某些情况下通过 API 提供给我的方法。感谢您的帮助!
  • 很高兴能为您提供帮助! :) 是否在本地(在您的服务器上的数据库中)存储 API 来源的数据或每次都去获取它总是一个困难的决定。主要挑战是知道您的数据库数据何时过期并已远程更新。
猜你喜欢
  • 2021-09-25
  • 2023-02-05
  • 2021-12-22
  • 2021-09-12
  • 2018-11-23
  • 1970-01-01
  • 2020-04-21
  • 2021-04-12
  • 1970-01-01
相关资源
最近更新 更多