Cara mengonversi hasil ActiveRecord menjadi larik hash

112

Saya memiliki hasil ActiveRecord dari operasi pencarian:

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

Sekarang saya ingin mengonversi hasil ini menjadi array hash seperti ini:

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

sehingga saya akan dapat mengulang melalui array dan menambahkan lebih banyak elemen ke hash dan kemudian mengubah hasilnya menjadi JSONuntuk respons API saya. Bagaimana saya bisa melakukan ini?

Avinash Mb
sumber

Jawaban:

210

as_json

Anda harus menggunakan as_jsonmetode yang mengubah objek ActiveRecord menjadi Ruby Hashes meskipun namanya

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

Anda juga dapat mengonversi objek ActiveRecord apa pun menjadi Hash dengan serializable_hashdan Anda dapat mengonversi hasil ActiveRecord apa pun menjadi Array dengan to_a, jadi sebagai contoh:

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

Dan jika Anda menginginkan solusi jelek untuk Rails sebelum v2.3

JSON.parse(tasks_records.to_json) # please don't do it
hdorio
sumber
4
+1 Untuk menyarankan serializable_hash - ini adalah pertama kalinya saya menemukan jawaban yang menyebutkan ini. Sayangnya saya saat ini menggunakan solusi JSON terakhir, tetapi sekarang akan melihat menggunakan serializable_hash. Saya hanya perlu mencari tahu cara memasukkan nama kelas dengan setiap record, sama seperti yang mungkin Anda dapatkan jika menyertakan root di JSON.
Dom
@Dom 웃 Jika saya mengerti dengan benar lihat ini: stackoverflow.com/questions/17090891/…
hdorio
@Dom lihat jawaban saya di bawah.
Fredrik E
Cara lain yang mungkin adalah tasks_records = TaskStoreStatus.all.map(&:attributes).
Rigo
Solusi yang benar-benar hebat di sini, tetapi pertanyaan saya adalah Apa manfaat menggunakan keduanya .as_json, &:serializable_hashdan &:attributes? Apakah ini ada hubungannya dengan pembantu ActiveRecord atau langsung dengan kinerja? terima kasih sebelumnya guys! @Dom @Rigo @Fredrik E
alexventuraio
35

Mungkin?

result.map(&:attributes)

Jika Anda membutuhkan tombol simbol:

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

Untuk ActiveRecord saat ini (4.2.4+), ada metode to_hashpada Resultobjek yang mengembalikan array hashes. Anda kemudian dapat memetakannya dan mengubahnya menjadi hash yang disimbolkan:

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

Lihat dokumen ActiveRecord :: Result untuk info lebih lanjut .

sventechie.dll
sumber
Tidak bisa lebih sederhana dan lebih jelas dari ini. Terima kasih banyak.
WM
1
Catatan jika versi ActiveRecord Anda tidak mengenali to_hashmetode: coba to_arysaja. Anehnya ini berhasil untuk saya.
Phil