繁体   English   中英

使用Ruby on Rails解析Json数据

[英]Parse Json Data with Ruby on Rails

目标:解析数据以显示erb文件中的所有id

问题:由于这段代码@x = obj[i]["id"] NoMethodError in DemoController#index

当我用数字替换上面代码中的“ i”时,显示一个id号,这使我相信while循环是正确的。 它只是不明白“ i”是什么。

我究竟做错了什么?

这是我的Controller和View的代码

demo_controller.rb

require 'rubygems'
require 'json'
require 'net/http'
require 'httparty'
class DemoController < ApplicationController

  respond_to :json
  $angelURI = "https://api.angel.co/1/jobs"

  def index
    response = HTTParty.get('https://api.angel.co/1/jobs/')
    obj = JSON.parse(response.body)["jobs"]
    arraylength = obj.length

    i = 0
    while i <= arraylength do
      @x = obj[i]["id"]
      i += 1

    end


  end
end

index.html.erb

<%=@x%>
  1. 您要在循环的每个级别为同一@x变量分配一个值-这将以@x具有最后一个id的值结尾-这是预期的行为吗?

  2. 我现在看不到您的数组有什么奇怪的东西,但是Ruby倾向于将它们都用于:

     obj.each do |elem| @x = elem["id"] end 

Upate:在zishe很好地了解了循环之后,使用每个循环也避免了此类问题(“我需要转到ith元素还是停在ith-1”?)。

iwhile循环的计数器,这是基础。 我想你循环到更多,在<上更改<=

i = 0
while i < arraylength do
  @x = obj[i]["id"]
  i += 1
end

或者像马丁建议的那样做得更好。

通过结合最佳答案,我们得到:

@x = []
obj.each do |job|
  @x << job["id"]
end

因此,您遇到了一个错误的错误:while循环运行得太远了(由于<= )。 简单的解决方案:使用each计数器(这样您就不必自己维护计数器了-为什么要加倍努力)。 但最重要的是,我建议在lib中添加一个文件来进行页面解析。

因此,例如添加一个名为lib/jobs_parser.rb的文件,其中包含类似

require 'httparty'

module JobsParser

  ANGEL_JOBS_URI = "https://api.angel.co/1/jobs"

  def all_job_ids
    all_jobs.map{|j| j["id"]} 
  end

  def all_jobs
    response = HTTParty.get(ANGEL_JOBS_URI)
    jobs = JSON.parse(response.body)["jobs"]
  end
end

我在这里做什么: map生成仅包含"id"字段的数组。 我认为在这个级别上保留完整的作业或ID数组更有意义。

注意:我大大缩短了require语句列表,大多数应该通过您的Gemfile自动Gemfile

然后在您的控制器中可以编写:

class DemoController < ApplicationController

  def index
    all_job_ids = JobsParser.all_job_ids
    @x = all_job_ids.last
  end

end

和您的看法保持不变:)

这样的好处是,您可以通过测试简单地测试JobsParser ,或者在rails console手动进行测试,并且代码更具可读性。

您的代码中有一个错误的错误。 基本上,您正在遍历数组,然后尝试访问比数组中多的一个元素,该元素然后返回nil ,自然不充当哈希。

假设您的obj是一个包含3个元素的数组,因此arraylength为3。 现在你取从阵列4个元素,用的索引的元素012 ,和3 因为只有3个元素0..2 ,所以最后一个obj[3]不存在。

为了保留现有代码,您可以将循环更改如下:

while i < arraylength do
  #...
end

但是,仅获取数组中最后一个元素的ID,使用惯用的红宝石并将整个算法写为

def index
  response = HTTParty.get('https://api.angel.co/1/jobs/')
  jobs = JSON.parse(response.body)["jobs"]

  @x = jobs.last["id"]
end

暂无
暂无

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

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