无法访问Ruby / Rails中的嵌套数据和Nil

时间:2019-04-21 02:32:54

标签: ruby-on-rails arrays ruby data-structures null

我正在Rails应用程序中从外部API获取数据以用于React前端。我想在数据到达前端之前清理数据,并尝试在不可预测的API响应中到达嵌套数据。有时,嵌套数据返回某些内容,而其他时候则返回nil。这是问题(我认为)。

我尝试了有条件的各种保护措施,但这似乎不起作用。

这是我正在使用的方法:

def song_details
    search = HTTParty.get("https://musicbrainz.org/ws/2/release/#{params[:songId]}?inc=artist-credits+artist-rels+media+recording-level-rels+url-rels+work-level-rels+recording-rels&fmt=json", {
      headers: {"User-Agent" => "Songly/ver 1.0", "Contact" => "demiansims@gmail.com"}
      })


end

如果我在Rails Console中调用search['relations'][0]['artist']['name'],则会得到一个漂亮的名称字符串。

如果我尝试运行:

search['relations'].map { |r| r['artist'].each { |a| puts a['name'] }}

我收到no method for Nil class on []错误。我知道这是因为某些值是Nil。

这里是嵌套数据的完整图片(价值1次迭代-其中约有20种):

{"end"=>nil,
 "attribute-values"=>{},
 "artist"=>
  {"id"=>"70047e57-0153-4117-b0fc-a1d2e322e5ef",
   "name"=>"Donald Fagen",
   "disambiguation"=>"",
   "sort-name"=>"Fagen, Donald"},
 "ended"=>false,
 "direction"=>"backward",
 "type-id"=>"01ce32b0-d873-4baa-8025-714b45c0c754",
 "begin"=>nil,
 "target-type"=>"artist",
 "target-credit"=>"",
 "type"=>"composer",
 "attributes"=>[],
 "attribute-ids"=>{},
 "source-credit"=>""}

我试图从relations -> artist -> name中获取名称,即使有一个“艺术家”或“名称”,但不等于nil。我该如何处理?抱歉,我是Rails的新手,刚开始尝试使用数据结构。而且我认为我在发送到React之前处理好后端中的数据是正确的吗?

编辑

以下建议更加接近,但在尝试包装数据时仍然出现错误:

  def song_details
    search = HTTParty.get("https://musicbrainz.org/ws/2/release/#{params[:songId]}?inc=artist-credits+artist-rels+media+recording-level-rels+url-rels+work-level-rels+recording-rels&fmt=json", {
      headers: {"User-Agent" => "Songly/ver 1.0", "Contact" => "demiansims@gmail.com"}
      })
      search['relations'].present?
        search['relations'].map do |r|
          r['artist'].present?
          artist = {
            name: r['artist', 'name'],
            role: r['type'].present? && r['type'],
            id: r['artist', 'id'],
            disambiguation: r['artist', 'disambiguation'],
            attributes: r['attributes'] && r['attributes'].each { |a| a }
          }
      end
    artist
  end

我收到如下错误:

app/controllers/api/v1/searches_controller.rb:26:in `[]'
app/controllers/api/v1/searches_controller.rb:26:in `block in song_details'
app/controllers/api/v1/searches_controller.rb:21:in `map'
app/controllers/api/v1/searches_controller.rb:21:in `song_details'

2 个答案:

答案 0 :(得分:1)

这是一个很好的示例,您可以在其中使用Hash#dig

artist_names = search['relations'].map { |r| r.dig('artist', 'name') }

答案 1 :(得分:0)

您可以在rails中使用try方法try方法返回nil,如果对象中不存在数据,请参考this链接以供参考,如果不起作用,请使用a.present?或{ {1}}

如果您想检查nil,则使用您提供的示例,并假设它将在数组中,您可以使用

a.blank?

您做错了r ['artist','name']引发错误

a.map { |r|  r['artist'] && r['artist']['name'] } //a is array of object you specified

结束