Cómo convertir los resultados de ActiveRecord en una matriz de hashes

112

Tengo un resultado de ActiveRecord de una operación de búsqueda:

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

Ahora quiero convertir estos resultados en una matriz de hashes como este:

[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" }

para poder iterar a través de la matriz y agregar más elementos a los hash y luego convertir el resultado en JSONmi respuesta API. ¿Cómo puedo hacer esto?

Avinash Mb
fuente
Véase también stackoverflow.com/q/20794398/165673
Yarin

Respuestas:

210

as_json

Debe usar el as_jsonmétodo que convierte los objetos ActiveRecord a Ruby Hashes a pesar de su nombre

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

También puede convertir cualquier objeto ActiveRecord en un Hash con serializable_hashy puede convertir cualquier resultado de ActiveRecord en un Array con to_a, por lo que para su ejemplo:

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

Y si quieres una solución fea para Rails antes de la v2.3

JSON.parse(tasks_records.to_json) # please don't do it
hdorio
fuente
4
+1 Por sugerir serializable_hash: esta es la primera vez que me encuentro con una respuesta que menciona esto. Lamentablemente, actualmente estoy usando la última solución JSON, pero ahora veré el uso de serializable_hash. Solo necesito averiguar cómo incluir el nombre de la clase con cada registro, igual que podría obtener si incluye root en JSON.
Dom
@Dom 웃 Si entiendo correctamente, vea esto: stackoverflow.com/questions/17090891/…
hdorio
@Dom vea mi respuesta a continuación.
Fredrik E
Otra forma posible es tasks_records = TaskStoreStatus.all.map(&:attributes).
Rigo
Realmente grandes soluciones más aquí, pero mi pregunta podría ser ¿Cuáles son los beneficios de usar cualquiera .as_json, &:serializable_hashy &:attributes? ¿Tiene que ver con los ayudantes de ActiveRecord o directamente con el rendimiento? gracias de antemano chicos! @Dom @Rigo @Fredrik E
alexventuraio
35

¿Tal vez?

result.map(&:attributes)

Si necesita claves de símbolos:

result.map { |r| r.attributes.symbolize_keys }
Elena Unanyan
fuente
9

Para ActiveRecord actual (4.2.4+), hay un método to_hashen el Resultobjeto que devuelve una matriz de hashes. Luego puede mapearlo y convertirlo en hashes simbolizados:

# 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"},
      ...
     ]

Consulte los documentos de ActiveRecord :: Result para obtener más información .

sventechie
fuente
No puede ser más simple y claro que esto. Muchas gracias.
WM
1
Una nota si su versión de ActiveRecord no reconoce el to_hashmétodo: intente en su to_arylugar. Curiosamente esto funcionó para mí.
Phil