如何将ActiveRecord的结果转换为哈希数组

142

我有一个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响应。我该如何做到这一点?


请参见https://dev59.com/9GIi5IYBdhLWcg3w9gJy。 - Yarin
4个回答

258

as_json

您应该使用 as_json 方法,尽管其名称如此,它将 ActiveRecord 对象转换为 Ruby 哈希表

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

您还可以使用 serializable_hash 将任何 ActiveRecord 对象转换为哈希表,使用 to_a 将任何 ActiveRecord 结果转换为数组。因此,对于您的示例:

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

6
感谢您建议使用 serializable_hash,这是我第一次看到提到这个答案。遗憾的是我目前正在使用最后一个 JSON 解决方案,但现在将考虑使用 serializable_hash。我只需要找出如何在每个记录中包含类名,就像在 JSON 中包含根节点一样。 - Dom
如果我理解正确,请参考这个链接:https://dev59.com/6XPYa4cB1Zd3GeqPg0e5 @Dom웃 - hdorio
1
@Dom请看下面我的回答。 - Fredrik E
2
另一种可能的方法是 tasks_records = TaskStoreStatus.all.map(&:attributes) - Rigo
这里有很棒的解决方案,但我的问题可能是:“使用.as_json&:serializable_hash&:attributes有什么好处?这与ActiveRecord助手还是直接与性能有关?”谢谢大家!@Dom @Rigo @Fredrik E - alexventuraio

52

可能吗?

result.map(&:attributes)

如果您需要符号键:

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

15

对于当前的ActiveRecord(4.2.4+),Result对象有一个to_hash方法,返回一个哈希数组。然后你可以对它进行映射,并将其转换为符号哈希:

# 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 文档了解更多信息.


没有比这更简单和清晰的了。非常感谢。 - W.M.
1
如果你的 ActiveRecord 版本无法识别 to_hash 方法,请尝试使用 to_ary。奇怪的是,这对我起作用了。 - Phil

1
尝试这个:
数据 = Model_name.最后
数据属性

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接