Cách chuyển đổi kết quả ActiveRecord thành một mảng băm


112

Tôi có kết quả ActiveRecord của thao tác tìm:

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

Bây giờ tôi muốn chuyển đổi kết quả này thành một mảng băm như thế này:

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

để tôi có thể lặp lại qua mảng và thêm nhiều phần tử hơn vào hàm băm và sau đó để chuyển đổi kết quả thành JSONcho phản hồi API của tôi. Tôi có thể làm cái này như thế nào?


Câu trả lời:


210

as_json

Bạn nên sử dụng as_jsonphương pháp chuyển đổi các đối tượng ActiveRecord thành Ruby Hashes mặc dù tên của nó

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

Bạn cũng có thể chuyển đổi bất kỳ đối tượng ActiveRecord nào thành Hash với serializable_hashvà bạn có thể chuyển đổi bất kỳ kết quả ActiveRecord nào thành Mảng với to_a, ví dụ như sau:

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

Và nếu bạn muốn một giải pháp xấu cho Rails trước phiên bản v2.3

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

4
+1 Để đề xuất serializable_hash - đây là lần đầu tiên tôi bắt gặp câu trả lời đề cập đến điều này. Đáng buồn là tôi hiện đang sử dụng giải pháp JSON cuối cùng, nhưng bây giờ sẽ xem xét việc sử dụng serializable_hash. Tôi chỉ cần tìm hiểu cách bao gồm tên lớp với mỗi bản ghi, giống như cách bạn có thể nhận được nếu bao gồm root trong JSON.
Dom

@Dom 웃 Nếu tôi hiểu thấy một cách chính xác này: stackoverflow.com/questions/17090891/...
hdorio

@Dom xem câu trả lời của tôi bên dưới.
Fredrik E

Một cách khác có thể là tasks_records = TaskStoreStatus.all.map(&:attributes).
Rigo

Các giải pháp thực sự tuyệt vời ở đây, nhưng câu hỏi của tôi có thể là Lợi ích của việc sử dụng một trong hai .as_json, &:serializable_hash&:attributes? Nó có liên quan đến trình trợ giúp ActiveRecord hay trực tiếp với hiệu suất không? cảm ơn trước guys! @Dom @Rigo @Fredrik E
alexventuraio

35

Có lẽ?

result.map(&:attributes)

Nếu bạn cần các phím biểu tượng:

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

9

Đối với ActiveRecord (4.2.4+) hiện tại, có một phương thức to_hashtrên Resultđối tượng trả về một mảng băm. Sau đó, bạn có thể ánh xạ lên nó và chuyển đổi thành các hàm băm được ký hiệu:

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

Xem tài liệu ActiveRecord :: Kết quả để biết thêm thông tin .


Không thể đơn giản và rõ ràng hơn thế này. Cảm ơn rât nhiều.
WM

1
Lưu ý nếu phiên bản ActiveRecord của bạn không nhận dạng được to_hashphương pháp: hãy thử to_arythay thế. Kỳ lạ là điều này đã làm việc cho tôi.
Phil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.