2013-03-27 20 views
6

Ho la seguente stringa JSON restituita da un server remoto:Parse JSON con una serie in Rails

{ 
    "users": [ 
    { 
     "user_id": 1, 
     "name": "Chris Rivers", 
    }, 
    { 
     "user_id": 3, 
     "name": "Peter Curley", 
    } 
    ] 
} 

vorrei iterare gli utenti.

ActiveSupport::JSON.decode(response.body)["users"].each do |user| 
    puts user["name"] 
end 

Per quanto ho capito, il problema è: ruby ​​non riconosce ActiveSupport::JSON.decode(response.body)["users"] come un array, e quindi puts mi restituisce solo il primo utente.

Come risolvere il problema?

risposta

9

Ciò che è stato incollato non è un JSON valido. Il finale virgola dopo su ogni "name" è un problema

"name": "Chris Rivers", 

Otterrete un LoadError cercando di decodificare questo con ActiveSupport::JSON.decode

MultiJson::LoadError: 399: unexpected token at '{"user_id": 1,"name": "Chris Rivers",},{"user_id": 3,"name": "Peter Curley",}]}'

Se puliamo il JSON, trasformandolo in qualcosa di ActiveSupport::JSON.decode possono capire

"{\"users\": [{\"user_id\": 1,\"name\": \"Chris Rivers\"},{\"user_id\": 3,\"name\": \"Peter Curley\"}]}" 

vedrete non v'è alcun problema di iterazione di ogni oggetto in "users" (x seguito è la stringa JSON sopra)

[8] pry(main)> ActiveSupport::JSON.decode(x)["users"].map { |user| user["name"] } 
=> ["Chris Rivers", "Peter Curley"] 
6

Il problema non è non riconosce la matrice, è la virgola finale dopo il "name" elementi.

Rimozione quelli permette JSON parsing procedere normalmente:

pry(main)> ActiveSupport::JSON.decode(s)["users"] 
=> [{"user_id" => 1, "name" => "Chris Rivers"}, 
    {"user_id" => 3, "name" => "Peter Curley"}] 
6

Vuol i dati di origine in realtà hanno le virgole finali dopo il nome di ciascun utente? Ricevo un errore di analisi per questo, ma il tuo codice funziona come vuoi se li rimuovo:

json = '{ "users": [ { "user_id": 1, "name": "Chris Rivers" }, { "user_id": 3, "name": "Peter Curley" } ]}' 
ActiveSupport::JSON.decode(json)["users"].each do |user| 
    puts user["name"] 
end