[英]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%>
您要在循环的每个级别为同一@x变量分配一个值-这将以@x具有最后一个id的值结尾-这是预期的行为吗?
我现在看不到您的数组有什么奇怪的东西,但是Ruby倾向于将它们都用于:
obj.each do |elem| @x = elem["id"] end
Upate:在zishe很好地了解了循环之后,使用每个循环也避免了此类问题(“我需要转到ith元素还是停在ith-1”?)。
i
是while
循环的计数器,这是基础。 我想你循环到更多,在<
上更改<=
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个元素,用的索引的元素0
, 1
, 2
,和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.