【问题标题】:Parse Json Data with Ruby on Rails使用 Ruby on Rails 解析 Json 数据
【发布时间】:2014-07-02 06:58:27
【问题描述】:

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

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

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

我做错了什么?

这是我的控制器和视图代码

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%>

【问题讨论】:

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


    【解决方案1】:
    1. 您在循环的每一层都为相同的@x 变量赋值——这将以@x 的最后一个id 的值结束——这是预期的行为吗?

      李>
    2. 我现在没有看到你的数组有什么奇怪的地方,但是 Ruby 倾向于将 each 用于:

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

    更新:跟随 zishe good catch 关于循环,使用 each 也避免了那种问题(“我需要去第 i 个元素还是停在第 ith-1 处”)。

    【讨论】:

    • 感谢“.each”提示!
    【解决方案2】:

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

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

    【讨论】:

    • 这正是我想要的。非常感谢!
    【解决方案3】:

    iwhile 循环中的计数器,它是基础。我认为你循环到更多,在 &lt; 上更改 &lt;=

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

    或者最好像马丁建议的那样去做。

    【讨论】:

    • 我忽略了“
    【解决方案4】:

    因此,您遇到了一个错误:您的 while 循环运行得太远(因为 &lt;=)。简单的解决方案:使用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 自动要求。

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

    class DemoController < ApplicationController
    
      def index
        all_job_ids = JobsParser.all_job_ids
        @x = all_job_ids.last
      end
    
    end
    

    你的观点保持不变:)

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

    【讨论】:

    • 哇!这对制作帮助文件非常有帮助。我一定要试试看。非常感谢您的澄清!
    【解决方案5】:

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

    假设您的 obj 是一个包含 3 个元素的数组,因此 arraylength 是三个。您现在从数组中获取 4 个元素,索引为 0123 的元素。由于您只有 3 个元素 0..2,因此最后一个 obj[3] 不存在。

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

    while i < arraylength do
      #...
    end
    

    但是,要获取数组中最后一个元素的 id,使用惯用的 ruby​​ 并将整个算法编写为更清晰(也更快)

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

    【讨论】:

    • 不知道“.last” 感谢您的提示!
    猜你喜欢
    • 2019-06-11
    • 2010-12-22
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 2012-04-30
    相关资源
    最近更新 更多