GooglePlacesAPIで取得したデータをデータベースへ保存する

# 初めに
初めまして。Jintaと申します。
個人開発をするにあたって、GooglePlacesAPIから取得したデータをデータベースに保存することがあったので、同じような状況の方のために、記録として残します。

# テーブルの作成
まず、取得したデータを保存するテーブルを作成します。
GooglePlacesAPIから取得できるデータは、一部ですが記事にまとめたのでこちらをご覧ください。
[Google Places APIを使用して情報を取得（Rails）](https://qiita.com/cheetah_02/items/d7c62be909ac4edca5d2)

テーブルの作成（マイグレーションファイル）
``` ruby:2023083120000_create_shops.rb
class CreateShops < ActiveRecord::Migration[7.0]
  def change
    create_table :shops do |t|
      t.string :name, null: false #店名
      t.string :postal_code       #郵便番号
      t.string :address           #住所
      t.string :phone_number      #電話番号
      t.string :opening_hours     #営業時間
      t.string :web_site          #ウェブサイト
      t.decimal :latitude, precision: 10, scale: 7, null: false #緯度
      t.decimal :longitude, precision: 10, scale: 7, null: false #経度
      t.string :place_id, null: false #プレイスID

      t.timestamps
    end
  end
end

```
``` 
bin/rails db:migrate
```


# 取得したいデータの情報をcsvファイルに書き出す
情報を取得する流れとして、
取得したいショップの電話番号（国際番号）をcsvファイルにまとめる→電話番号（国際番号）からplace_idを取得する→取得したplace_idから必要な詳細情報を取得する。
なので、csvファイルに取得したいショップの電話番号を書き出します。
csvファイルは以下の通り
``` csv:lib/cafe.csv
都道府県,店名,電話番号
東京,STARBUCKS RESERVE® ROASTERY TOKYO,+81 3-6417-0202
```

# rakeタスクでデータベースへの保存処理を実行する
``` ruby:lib/tasks/get_cafe_shop_details.rake
require 'csv' #csvファイルを操作するライブラリの読み込み
require 'open-uri' #open-uriライブラリを読み込んでいる
API_KEY = ENV['API_KEY'] #.envに記述しているAPIキーを代入

namespace :Cafe do
  desc 'Fetch and save shop details'
  task :get_and_save_details => :environment do
    #電話番号からplace_idを取得するメソッド
    def get_place_id(phone_number)
      client = GooglePlaces::Client.new(API_KEY)
      spot = client.spots_by_query(phone_number).first
      spot.place_id if spot
    end

    #place_idから詳細情報を取得するメソッド
    def get_detail_data(shop)
      place_id = get_place_id(shop['電話番号'])

      if place_id
        #クエリーパラメータの作成
        place_detail_query = URI.encode_www_form(
          place_id: place_id,
          language: 'ja',
          key: API_KEY
        )
        #PlacesAPIのエンドポイントの作成
        place_detail_url = "https://maps.googleapis.com/maps/api/place/details/json?#{place_detail_query}"
        #APIから取得したデータをテキストデータ（JSON形式）で取得し、変数に格納
        place_detail_page = URI.open(place_detail_url).read
        #JSON形式のデータを、Rubyオブジェクトに変換
        place_detail_data = JSON.parse(place_detail_page)

        #取得したデータを保存するカラム名と同じキー名で、ハッシュ（result）に保存
        result = {}
        result[:name] = shop['店名']
        result[:postal_code] = place_detail_data['result']['address_components'].find { |c| c['types'].include?('postal_code') }&.fetch('long_name', nil)

        full_address = place_detail_data['result']['formatted_address']
        result[:address] = full_address.sub(/\A[^ ]+/, '')

        result[:phone_number] = place_detail_data['result']['formatted_phone_number']
        result[:opening_hours] = place_detail_data['result']['opening_hours']['weekday_text'].join("\n") if place_detail_data['result']['opening_hours'].present?
        result[:web_site] = place_details_data['result']['website']
        result[:latitude] = place_detail_data['result']['geometry']['location']['lat']
        result[:longitude] = place_detail_data['result']['geometry']['location']['lng']
        result[:place_id] = place_id
        result[:web_site] = place_detail_data['result']['website']

        result
      else
        puts "詳細情報が見つかりませんでした。"
        nil
      end
    end

    #csvファイルを読み込む
    csv_file = 'lib/cafe.csv'
    #csvファイルの繰り返し処理で実行しデータベースへ保存
    CSV.foreach(csv_file, headers: true) do |row|
      shop_data = get_detail_data(row)
      if shop_data
        shop = Shop.create!(shop_data)
        puts "#{row['店名']}を保存しました"
        puts "----------"
      else
        puts "#{row['店名']}の保存に失敗しました"
      end
    end
  end
end

```



# 終わりに
初めてAPIを使用したので、割と時間がかかってしまいましたが、正常に保存ができて良かったです。
個人開発で発見のあった事は、なるべく記事にしていきたいと思います。
最後までご覧いただきありがとうございました。