ruby-on-rails - 如何迭代哈希数据对象并存储在 Rails 中的 SQLite 数据库中?
问题描述
我正在处理 JSON 数据。使用 gem 从 URL 获取 JSON 数据httparty
效果很好。现在我想迭代哈希数据对象并存储在 SQLite 数据库中。
# HTTParty response
@sett = {
"restaurant_name": "Restaurant 3",
"address": "xyz address",
"country": "United States",
"currency": "USD",
"client_key": "12345",
"client_name": "Client 3"
}
我想像这样将这个 JSON 数据存储在数据库中:
+-----------------+---------------+
| meta_key | meta_value |
+-----------------+---------------+
| restaurant_name | abc restatant |
| country | USA |
| ... | ... |
+-----------------+---------------+
def index
require 'httparty'
@setting = HTTParty.get(
'http://codekyt.in/froodle-wp/wp-json/data/v2/projects?client_key=12345',
headers: { 'Content-Type' => 'application/json' }
)
@sett = @setting.parsed_response
@sett.each_key do |key, value|
m = Setting.new
m.meta_data = key
m.meta_value = value
m.save
end
end
它存储但以数组而不是哈希的格式。
在数据库中,
t.string :meta_data
t.string :meta_value
解决方案
您的代码示例中有几处出错。
当您遍历您使用的哈希时
Hash#each_key
。它只遍历键,而不是值。@sett.each_key do |key, value| # ^- will always be nil
要正确循环键/值对,请使用
Hash#each
.您
save
在 void 上下文中调用。无法保存记录时会发生什么?目前它在设置记录上设置错误并返回false
,但返回值和错误都被忽略。这意味着如果一条记录由于某种原因无法保存,它就会被忽略。您可能希望使用它save!
来在失败的情况下引发异常。或者,您可以处理save
返回值。你怎么知道哪些记录属于一起?您当前只是保存
meta_data
和meta_value
. 当您保存来自多个请求的设置时会发生什么?可以通过将关联添加到其他模型来解决此问题。导致代码:
request = Request.create!(url: url) @sett.each do |key, value| request.settings.create!( meta_data: key, meta_value: value ) end
或者,您可以像这样使用自己管理此列:
request_nr = Setting.maximum(:request_nr) || 0 request_nr += 1 @sett.each do |key, value| Setting.create!( request_nr: request_nr, meta_data: key, meta_value: value ) end
如果上述问题得到解决,您可以通过执行以下操作将一组记录转换为哈希。
# First you need to fetch the records that belong together.
Setting.where(request_nr: 1)
#=> #<ActiveRecord::Relation [#<Setting id: 1, meta_data: ...>, ...]>
# The above will result in an collection of records, however we only care
# about the key/value. We can use `pluck` to get those values.
Setting.where(request_nr: 1).pluck(:meta_data, :meta_key)
#=> [["restaurant_name", "Restaurant 3"], ["address", "xyz address"], ...]
# The above array can be converted to a hash by simply calling `to_h` on it.
Setting.where(request_nr: 1).pluck(:meta_data, :meta_key).to_h
#=> { "restaurant_name" => "Restaurant 3", "address" => "xyz address", ... }
参考:
我已经在答案本身中提供了大多数链接。然而,这里有一些在文本中没有提到的代码块中使用的方法。
推荐阅读
- sql - 如何基于组为列中的所有 NULL 值分配非 Null 值?
- azure - 使用 ARM 模板有条件地部署带有子网的路由表
- python - 在python中转置管道分隔的csv
- tensorflow - TensorRT 的上采样张量
- javascript - 在浏览器中处理 SAML IdP 响应和断言
- javascript - 在 ReactJS 中更改组件时如何修复错误覆盖 CSS
- javascript - 我正在尝试获取输入的值,但控制台显示为空
- javascript - 在节点js中循环回调函数
- python - How to make the inputs and model have the same shape (RLlib Ray Sagemaker reinforcement learning)
- java - 在使用 sql2o 关闭连接之前执行更多查询