【问题标题】:how can I iterate hash data object and store in SQLite database in rails?如何迭代哈希数据对象并存储在 Rails 中的 SQLite 数据库中?
【发布时间】:2019-06-17 23:53:00
【问题描述】:

我正在处理 JSON 数据。使用httparty gem 从 URL 获取 JSON 数据效果很好。现在我想迭代哈希数据对象并存储在 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

【问题讨论】:

  • 您可以使用t.json :meta_data 进行 json 数据存储,
  • 非常感谢@ray
  • 也许对 rails-5 有效:P

标签: ruby-on-rails json ruby httparty


【解决方案1】:

您的代码示例中有几处出错。

  1. 当您循环使用Hash#each_key 的哈希值时。它只遍历键,而不是值。

    @sett.each_key do |key, value|
    #                         ^- will always be nil
    

    要正确循环键/值对,请使用Hash#each

  2. 您在 void 上下文中调用 save。无法保存记录时会发生什么?目前它在设置记录上设置错误并返回false,但返回值和错误都被忽略。这意味着如果由于某种原因无法保存一条记录,它就会被忽略。您可能希望使用save! 来在失败的情况下引发异常。或者,您可以处理 save 返回值。

  3. 您如何知道哪些记录属于一起?您目前只是保存meta_datameta_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", ... }

参考资料:

我已经在答案本身中提供了大多数链接。但是这里有一些在代码块中使用的方法,在文本中没有提到。

【讨论】:

    【解决方案2】:

    在迁移中,添加

    def change
      add_column :settings, :meta_data, :json
    end
    

    或者在创建新表的情况下,

    t.json :meta_data # storing meta_data & meta_value in your code
    

    setting.rb 模型中,

    serialize: :meta_data, JSON
    

    在你的代码中,更改为,

      @setting = HTTParty.get(
        'http://codekyt.in/froodle-wp/wp-json/data/v2/projects?client_key=12345',
        :headers =>{'Content-Type' => 'application/json'}
      )
      Setting.create(meta_data: @setting.parsed_response)
    

    可以根据您的情况对上面要保存的关联对象进行一些小改动

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-17
      • 1970-01-01
      • 2013-05-12
      • 2013-02-07
      • 2010-11-17
      • 2023-03-24
      • 2020-10-02
      • 2012-11-25
      相关资源
      最近更新 更多