Как преобразовать результаты ActiveRecord в массив хешей

112

У меня есть результат операции поиска ActiveRecord:

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

Теперь я хочу преобразовать эти результаты в массив таких хэшей:

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

так что я смогу выполнить итерацию по массиву и добавить больше элементов в хеши, а затем преобразовать результат в JSONсвой ответ API. Как я могу это сделать?

Авинаш Мб
источник
См. Также stackoverflow.com/q/20794398/165673
Yarin

Ответы:

211

as_json

Вы должны использовать as_jsonметод, который преобразует объекты ActiveRecord в Ruby Hashes, несмотря на его название

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

Вы также можете преобразовать любые объекты ActiveRecord в хэш с помощью, serializable_hashи вы можете преобразовать любые результаты ActiveRecord в массив с помощью to_a, поэтому для вашего примера:

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

И если вам нужно уродливое решение для Rails до v2.3

JSON.parse(tasks_records.to_json) # please don't do it
HDorio
источник
4
+1 За предложение serializable_hash - я впервые сталкиваюсь с ответом, в котором это упоминается. К сожалению, в настоящее время я использую последнее решение JSON, но теперь рассмотрю использование serializable_hash. Мне просто нужно выяснить, как включить имя класса в каждую запись, как если бы вы включали root в JSON.
Dom
@Dom 웃 Если я правильно понимаю, посмотрите это: stackoverflow.com/questions/17090891/…
hdorio
@Dom см. Мой ответ ниже.
Fredrik E
Другой возможный способ tasks_records = TaskStoreStatus.all.map(&:attributes).
Риго
Здесь действительно отличные решения, но мой вопрос может заключаться в том, каковы преимущества использования того и другого .as_json, &:serializable_hashи &:attributes? Это связано с помощниками ActiveRecord или напрямую с производительностью? заранее спасибо, ребята! @Dom @Rigo @Fredrik E
alexventuraio
36

Может быть?

result.map(&:attributes)

Если вам нужны символьные клавиши:

result.map { |r| r.attributes.symbolize_keys }
Елена Унанян
источник
10

Для получения текущей ActiveRecord (4.2.4+) существует метод to_hashна Resultобъекте , который возвращает массив хешей. Затем вы можете сопоставить его и преобразовать в символизированные хэши:

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

См. Документацию по ActiveRecord :: Result для получения дополнительной информации .

sventechie
источник
Не может быть проще и яснее этого. Большое спасибо.
WM
1
Примечание, если ваша версия ActiveRecord не распознает to_hashметод: попробуйте to_aryвместо этого. Как ни странно, у меня это сработало.
Фил