Come convertire i risultati di ActiveRecord in una matrice di hash


112

Ho un risultato ActiveRecord di un'operazione di ricerca:

tasks_records = TaskStoreStatus.find(
  :all,
  :select => "task_id, store_name, store_region",
  :conditions => ["task_status = ? and store_id = ?", "f", store_id]
)

Ora voglio convertire questi risultati in una serie di hash come questo:

[0] ->  { :task_d => 10, :store_name=> "Koramanagala", :store_region=> "India" }

[1] -> { :task_d => 10, :store_name=> "Koramanagala", :store_region=> "India" }

[2] ->  { :task_d => 10, :store_name=> "Koramanagala", :store_region=> "India" }

in modo che sarò in grado di iterare attraverso l'array e aggiungere più elementi agli hash e successivamente convertire il risultato in JSONper la mia risposta API. Come posso fare questo?


Risposte:


210

as_json

Dovresti usare un as_jsonmetodo che converte gli oggetti ActiveRecord in Ruby Hash nonostante il suo nome

tasks_records = TaskStoreStatus.all
tasks_records = tasks_records.as_json

# You can now add new records and return the result as json by calling `to_json`

tasks_records << TaskStoreStatus.last.as_json
tasks_records << { :task_id => 10, :store_name => "Koramanagala", :store_region => "India" }
tasks_records.to_json

serializable_hash

Puoi anche convertire qualsiasi oggetto ActiveRecord in un hash con serializable_hashe puoi convertire qualsiasi risultato ActiveRecord in un array con to_a, quindi per il tuo esempio:

tasks_records = TaskStoreStatus.all
tasks_records.to_a.map(&:serializable_hash)

E se vuoi una brutta soluzione per Rails prima della v2.3

JSON.parse(tasks_records.to_json) # please don't do it

4
+1 Per aver suggerito serializable_hash: questa è la prima volta che mi imbatto in una risposta che lo menziona. Purtroppo attualmente sto utilizzando l'ultima soluzione JSON, ma ora esaminerò l'utilizzo di serializable_hash. Ho solo bisogno di scoprire come includere il nome della classe in ogni record, lo stesso che potresti ottenere se includi root in JSON.
Dom

@Dom 웃 Se ho capito bene vedo questo: stackoverflow.com/questions/17090891/...
hdorio

@ Dom vedi la mia risposta qui sotto.
Fredrik E

Un altro modo possibile è tasks_records = TaskStoreStatus.all.map(&:attributes).
Rigo

Soluzioni davvero fantastiche qui, ma la mia domanda potrebbe essere Quali sono i vantaggi dell'utilizzo di entrambi .as_json, &:serializable_hashe &:attributes? Ha a che fare con gli helper ActiveRecord o direttamente con le prestazioni? grazie in anticipo ragazzi! @Dom @Rigo @Fredrik E
alexventuraio

35

Può essere?

result.map(&:attributes)

Se hai bisogno di chiavi con simboli:

result.map { |r| r.attributes.symbolize_keys }

9

Per corrente ActiveRecord (4.2.4+) v'è un metodo to_hashin Resultoggetto che restituisce un array di hash. Puoi quindi mapparlo e convertirlo in hash simbolizzati:

# Get an array of hashes representing the result (column => value):
result.to_hash
# => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
      {"id" => 2, "title" => "title_2", "body" => "body_2"},
      ...
     ]

result.to_hash.map(&:symbolize_keys)
# => [{:id => 1, :title => "title_1", :body => "body_1"},
      {:id => 2, :title => "title_2", :body => "body_2"},
      ...
     ]

Vedere la documentazione di ActiveRecord :: Result per ulteriori informazioni .


Non può essere più semplice e più chiaro di così. Grazie mille.
WM

1
Una nota se la tua versione di ActiveRecord non riconosce il to_hashmetodo: prova to_aryinvece. Stranamente questo ha funzionato per me.
Phil
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.