2013-04-09 20 views
13

Ho bisogno di un loop che produce hash, non una matrice di oggetti. Ho questo:JBuilder loop che produce hash

json.service_issues @service.issues do |issue| 
    json.set! issue.id, issue.name 
end 

che risultati:

service_issues: [ 
    { 
    3: "Not delivered" 
    }, 
    { 
    6: "Broken item" 
    }, 
    { 
    1: "Bad color" 
    }, 
    { 
    41: "Delivery problem" 
    } 
] 

Ho bisogno di questo:

service_issues: { 
    3: "Not delivered", 
    6: "Broken item", 
    1: "Bad color", 
    41: "Delivery problem" 
} 

E 'possibile fare questo senza convertire risultato AR di hash manualmente?

risposta

24

Jbuilder dev qui.

Risposta breve: Sì. È possibile senza convertire array di modelli in hash.

json.service_issues do 
    @service.issues.each{ |issue| json.set! issue.id, issue.name } 
end 

ma probabilmente sarebbe più facile preparare l'hash in anticipo.

json.service_issues Hash[@service.issues.map{ |issue| [ issue.id, issue.name ] }] 
+0

Come potrei formattare le chiavi come numeri interi ? –

+2

@RichardCook no. Le chiavi dell'oggetto Javascript sono sempre stringhe. Quindi, in javascript myObject [2] è completamente equivalente a myObject ['2']. – rwz

+0

Il problema con il primo metodo è che se non ci sono '@ service.issues', non si otterrà un hash vuoto, la chiave non sarà presente nel JSON (nella mia esperienza). – Jalada

0

si può fare come questo senso

Jbuilder.encode do |json| 
    json.service_issues @service.issues.inject({}) { |hash, issue| hash[issue.id] = issue.name; hash } 
end 

Il codice che genera tecnica hash può essere compresa dal seguente esempio.

[1] pry(main)> array = [{id: 1, content: 'a'}, {id: 2, content: 'b'}] 
=> [{:id=>1, :content=>"a"}, {:id=>2, :content=>"b"}] 
[2] pry(main)> array.inject({}) { |hash, element| hash[element[:id]] = element[:content]; hash } 
=> {1=>"a", 2=>"b"} 

Il punto chiave di inject per generare hash, ritorno creato hash ogni dopo aver inserito nuovo elemento. Sopra l'esempio, è realizzato da ; hash.

2

Questa domanda è piuttosto vecchio, ma per chi è interessato ad avere un hash di array (oggetti), è possibile utilizzare il seguente codice:

@bacon_types.each do |bacon_type| 
json.set! bacon_type.name, bacon_type.bacons do |bacon| 
    bacon.title bacon.title 
    ... 
end 
Problemi correlati