如何从json响应创建对象数组

时间:2018-08-15 08:03:37

标签: ruby-on-rails json ruby ruby-on-rails-5

我收到此错误:

  

[“ id”,“ 6309”]:Array的未定义方法`name'

我想在每个响应比赛中显示联赛名称

Json回复:

{
    "success": 1,
    "pager": {
        "page": 1,
        "per_page": 50,
        "total": 21
    },
    "results": [
        {
            "id": "222434",
            "time": "1489669200",
            "time_status": "1",
            "league": {
                "id": "4148",
                "name": "Viareggio Cup",
                "cc": null
            },
            "home": {
                "id": "43717",
                "name": "Fiorentina U19",
                "image_id": "42466",
                "cc": "it"
            },
            "away": {
                "id": "159690",
                "name": "Garden City Panthers FC U19",
                "image_id": "320141",
                "cc": null
            },
            "timer": {
                "tm": 86,
                "ts": 4,
                "tt": "1"
            },
            "scores": {
                "2": {
                    "home": "2",
                    "away": "0"
                }
            }
        },
        {
            "id": "223265",
            "time": "1489669200",
            "time_status": "1",
            "league": {
                "id": "1501",
                "name": "Uganda Division 2",
                "cc": "ug"
            },
            "home": {
                "id": "159745",
                "name": "Simba FC",
                "image_id": null,
                "cc": null
            },
            "away": {
                "id": "80323",
                "name": "Busia Fisheries",
                "image_id": null,
                "cc": null
            },
            "timer": {
                "tm": 69,
                "ts": 1,
                "tt": "1"
            },
            "scores": {
                "2": {
                    "home": "1",
                    "away": "2"
                }
            }
        },
    ]
}

module Bapi
  class Inplay < Base
    attr_accessor :id,
                  :time,
                  :time_status,
                  :league

    CACHE_DEFAULTS = { expires_in: 7.days, force: false }

    def self.all(query = {})
      response = Request.where("/v2/events/inplay",query, CACHE_DEFAULTS)
      events = response.fetch('results', []).map { |inplay| Inplay.new(inplay) }
      [ events, response[:errors] ]
    end

    def initialize(args = {})
      super(args)
      league = parse_leagues(args)
    end


     private

    def parse_leagues(args = {})
      args.fetch("league", []).map { |league| League.new(league) }
    end
  end
end

 module Bap
     class Base
        attr_accessor :errors

        def initialize(args = {})
          args.each do |name, value|
            attr_name = name.to_s
            send("#{attr_name}=", value) if respond_to?("#{attr_name}=")
          end
        end
      end
    end

联赛模型

module Bapi
  class League < Base
    attr_accessor :id,
                  :name,
                  :cc
  end
end

控制器:

@events, @errors = Bapi::Inplay.all

观看次数:

<% @events.each_slice(3) do |events| %>
    <% events.each do |event| %>
     <% event.league.each do |leg| %>
            <%= leg.name %>      
     <% end %>
    <% end %>
  <% end %>
 <% end %>

[#<Bap::Inplay:0x00007feceede0570 @id="873482", @time="1534143600", @time_status="1", @league={"id"=>"6309", "name"=>"China Super League Reserves", "cc"=>"cn"}>, #<Bap::Inplay:0x00007feceedeb6f0 @id="875996", @time="1534147192", @time_status="1", @league={"id"=>"3653", "name"=>"Indonesia Cup", "cc"=>"id"}>]

当我这样更改代码时,就可以正常使用


   <% @events.each_slice(3) do |events| %>
        <% events.each do |event| %>
         <%= event.time %>
         <%= event.time_status %>         
        <% end %>
      <% end %>
     <% end %>

编辑: 我发现了这个
现在,当我使用键的返回值时,如何定义将参数转换为(键值)的变量

    <% @events.each_slice(3) do |events| %>
        <% events.each do |event| %>
     <% event.league.each do |k,v| %>
            <%= k %> <br>
            <%= v %>         
       <% end %>      
    <% end %>
  <% end %>
 <% end %>

1 个答案:

答案 0 :(得分:0)

我想问题出在这种方法上

def initialize(args = {})
  super(args)
  league = parse_leagues(args)
end

将联赛解析并设置为局部变量,但应将其设置为一个实例:

def initialize(args = {})
  super(args)
  @league = parse_leagues(args)
end

否则,将调用Base中的默认实现,并将@league设置为原始值(哈希)

parse_leagues方法也应该固定(并且可能重命名为parse_league,因为原始值不是数组,而是散列):

def parse_leagues(args = {})
  League.new(args.fetch("league", {}))
end

然后在视图中使用它,如下所示:

<% @events.each_slice(3) do |events| %>
  <% events.each do |event| %>
    <%= event.league.name %>    
  <% end %>
<% end %>