Comment convertir les résultats ActiveRecord en un tableau de hachages

112

J'ai un résultat ActiveRecord d'une opération de recherche:

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

Maintenant, je veux convertir ces résultats en un tableau de hachages comme celui-ci:

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

afin que je puisse parcourir le tableau et ajouter plus d'éléments aux hachages et plus tard convertir le résultat en JSONpour ma réponse API. Comment puis-je faire ceci?

Avinash Mb
la source

Réponses:

210

as_json

Vous devez utiliser une as_jsonméthode qui convertit les objets ActiveRecord en Ruby Hashes malgré son nom

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

Vous pouvez également convertir tous les objets ActiveRecord en un hachage avec serializable_hashet vous pouvez convertir tous les résultats ActiveRecord en un tableau avec to_a, donc pour votre exemple:

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

Et si vous voulez une solution moche pour Rails avant la v2.3

JSON.parse(tasks_records.to_json) # please don't do it
hdorio
la source
4
+1 Pour avoir suggéré serializable_hash - c'est la première fois que je rencontre une réponse mentionnant cela. Malheureusement, j'utilise actuellement la dernière solution JSON, mais je vais maintenant examiner l'utilisation de serializable_hash. J'ai juste besoin de savoir comment inclure le nom de la classe avec chaque enregistrement, comme vous pourriez l'obtenir si vous incluez root dans JSON.
Dom
@Dom 웃 Si je comprends bien, voyez ceci: stackoverflow.com/questions/17090891/…
hdorio
@Dom voir ma réponse ci-dessous.
Fredrik E
Un autre moyen possible est tasks_records = TaskStoreStatus.all.map(&:attributes).
Rigo
Vraiment super solutions ici, mais ma question pourrait être Quels sont les avantages de l' utilisation soit .as_json, &:serializable_hashet &:attributes? Est-ce que cela a à voir avec les assistants ActiveRecord ou directement avec les performances? merci d'avance les gars! @Dom @Rigo @Fredrik E
alexventuraio
35

Peut être?

result.map(&:attributes)

Si vous avez besoin de touches de symboles:

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

Pour ActiveRecord actuel (4.2.4+), il existe une méthode to_hashsur l' Resultobjet qui renvoie un tableau de hachages. Vous pouvez ensuite mapper dessus et convertir en hachages symbolisés:

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

Consultez la documentation ActiveRecord :: Result pour plus d'informations .

sventechie
la source
On ne peut pas être plus simple et plus clair que cela. Merci beaucoup.
WM
1
Une note si votre version d'ActiveRecord ne reconnaît pas la to_hashméthode: essayez à la to_aryplace. Étrangement, cela a fonctionné pour moi.
Phil