使用 Rails 将外部 JSON 保存到 DB

2021-11-15 00:00:00 api json ruby-on-rails migrate sqlite

我正在使用 gem 'httparty' 对外部源进行 GET 调用;这是我的 Controller.rb:

I'm making a GET call to an external source using the gem 'httparty'; here's my Controller.rb:

def show
  response = HTTParty.get('URI')
  user = JSON.parse(response)
  user.each {|line| puts line['user']['id']}
  #the "['user']['id']" is because of the nested JSON object that is returned after the 
  parse.
end

这会在我的 rails 控制台中返回正确的输出,但现在的问题是如何将 ['id'] 保存到我的数据库中?

This returns the correct output in my rails console, but now the question is how do I save the ['id'] to my db?

目前,我的 User 模型有 :id 和 :name;来自外部 API 的 JSON 对象发送 :id 和 :name 以及一堆我不需要的其他信息.

Currently, my User model has :id and :name; the JSON object from the external API sends :id and :name along with a bunch of other information I don't need.

class User < ActiveRecord::Base
   attr_accessor :id, :name
end

感谢任何帮助,谢谢!

推荐答案

首先,我建议您为 id 创建另一列(例如 external_id 或其他内容),而不是将其保存在User 模型的实际 id 列(该列在 ActiveRecord 中非常重要,您真的不想直接设置它).您可以验证该列的唯一性,以确保不会将相同的用户数据导入到数据库中的多个单独记录中.

First, I would suggest that you create another column for the id (say external_id or something), rather than saving it in the actual id column of the User model (that column is very important in ActiveRecord and you really don't want to be setting it directly). You can validate uniqueness on that column to ensure that you don't import the same user data into multiple separate records in the db.

拥有该列后,在您的 User 模型中创建一个类方法(我已将其称为 save_data_from_api)以将 JSON 数据加载到数据库中:

Once you have that column, create a class method in your User model (I've called mine save_data_from_api) to load the JSON data into the db:

class User < ActiveRecord::Base

  # optional, but probably a good idea
  validates :external_id, :uniqueness => true

  def self.save_data_from_api
    response = HTTParty.get('URI')
    user_data = JSON.parse(response)
    users = user_data.map do |line|
      u = User.new
      u.external_id = line['user']['id']
      # set name value however you want to do that
      u.save
      u
    end
    users.select(&:persisted?)
  end

end

这是做什么的:

  • 将 JSON 数据映射到一个块 ​​(user_data.map),它接受每个 JSON 用户和
  • Map the JSON data to a block (user_data.map) which takes each JSON user and
  1. 初始化一个新用户 (User.new)
  2. 为其分配 id JSON 数据 (line['user']['id'])
  3. 保存新用户(u.save),并且
  4. 返回它(块中的最后一个 u).
  1. initializes a new user (User.new)
  2. assigns it the id JSON data (line['user']['id'])
  3. saves the new user (u.save), and
  4. return its it (the last u in the block).

  • 然后,获取结果(分配给 users)并仅选择数据库中实际存在(被持久化)的结果 (users.select(&:persisted?)).例如,如果您对 external_id 有唯一性约束,并且您尝试再次加载 db 数据,u.save 将返回 false,不会(重新)创建记录,并且这些结果将从方法返回的结果中过滤掉.
  • Then, take the result (assigned to users) and select only those that actually exist (were persisted) in the db (users.select(&:persisted?)). For example, if you have a uniqueness constraint on external_id and you try to load the db data again, u.save will return false, the record will not be (re-)created, and those results will be filtered out of the results returned from the method.
  • 这可能是也可能不是您想要的返回值.此外,您可能希望在块中添加更多属性分配(name 等来自 JSON 数据).我让你来填写其他细节.

    This may or may not be the return value you want. Also, you probably want to add more attribute assignments (name, etc. from the JSON data) in the block. I leave it up to you to fill in those other details.

    相关文章