LoginSignup
5
4

More than 3 years have passed since last update.

APIデータをテーブルに保存する方法

Posted at

はじめに

ポートフォリオを作成していく中で楽天APIのデータをテーブルに保存したいと思い探すと以下の記事を見つけました
https://qiita.com/Hiroaki_jr/items/983b11a45e2b42c8f3dc
こちらの記事を参考に自分なりに改良してコードを書き直したので誰かの参考になればと思い書かせていただきます。

環境

ruby 2.6.5
rails 6.0.3
mysql 8.0.23

ER図

スクリーンショット 2021-04-06 12.06.45.png
ユーザー(Userモデル)がアイテム(Rakutenモデル)を購入したいリストとして登録(Buylistモデル)できるようなアソシエーションを作りました。

例としてはユーザーが投稿に対していいねができるのようなアソシエーションと同じだと思います。
Rakutenのカラムはjsonで送られてくるデータの中で必要なデータをカラムとして作成しました

Controller

テーブルの作成、ルーティングの記述、モデルのアソシエーションの設定は割愛させていただきます。
主にコントローラー、ビューの部分の記述を説明させていただきます。

rakutens_controller.rb

  def index
   #長いためprivetメソッドに定義
    create_rakuten_data(params)

    @items = Rakuten.all.page(params[:page])
    # 全アイテム数
    @total_count = @results.response.count
  end

  def search
    @items = @q.result.page(params[:page]).per(30)
    @count = @q.result.count
  end

  private
    #楽天市場の店指定のアイテムを取得
    def create_rakuten_data(params)
      @results = RakutenWebService::Ichiba::Item.search(
        shopCode: 'shop-senjin',
        page: params[:page],
        hits: 30)
    #ここで取得したアイテムをテーブルに保存するがすでに保存されているアイテムは保存しない処理を行う
      @results.each do |result|
        #取得したデータの配列のresultを引数にprivetメソッドreadを呼び出し
        item = Rakuten.new(read(result))
        #rakutensテーブルに同じアイテムがあれば保存しない処理
        unless Rakuten.all.exists?(item_name: item.item_name)
          item.save
        end
      end
    end

    def read(result)
      #Rakutenモデルのインスタンスに埋め込む
      image_url = result['mediumImageUrls'][0]
      item_name = result['itemName']
      item_price = result['itemPrice']
      item_url = result['itemUrl']
      shop_name = result['shopCode']
      genre_id = result['genreId']
      review_average = result['reviewAverage']
      {
        image_urls: image_url,
        item_name: item_name,
        item_price: item_price,
        item_url: item_url,
        shop_name: shop_name,
        genle_id: genre_id,
        review_average: review_average
      }
    end

楽天APIで取得したBooksデータには一意なカラム「isbn」があるが、Itemには一意なカラムがないためitem_nameを一意のカラムとして扱いました。

View

rakutens/index.html.haml
.senjin-search
    = search_form_for @q, url: search_rakutens_path do |f|
      .text-center.my-3
        %h4.my-2.font-weight-bold キーワード検索
        = f.search_field :item_name_or_item_price_cont, class: 'senjin-field'
        = button_tag type: 'submit', class: 'icon senjin-icon' do
          %i.fas.fa-search
      .text-center.my-3
        %h4.my-2.font-weight-bold ジャンル検索
        = f.select :genle_id_eq, {'バッグ、ポーチ、入れ物': 213693, 'バックパック,リュック': 111926, '手袋': 509058, '靴下': 408907, '小物,装具': 213694, 'Tシャツ': 551180, 'コンパス': 208078, 'GPS': 402305, 'サングラス、ゴーグル、フェイスフード': 213692, 'クッション、ベッド部品': 111925, 'ビニールテープ': 301594, 'ジャケット': 558873, '身分証入れ': 403809, 'トレーニングウェア': 302491, 'マット類': 501931}, { include_blank: '指定なし'}, class: 'senjin-field'
        = button_tag type: 'submit', class: 'icon senjin-icon' do
          %i.fas.fa-search
  .senjin-counts
    全アイテム数: #{@total_count} 件
  .container 
    .row
      = render 'commons/rakuten_item', items: @items
    = paginate @items
commons/rakuten_item
- items.each do |item|
  .col-sm-4.col-md-4.col-lg-3.col-xl-2.mb-3
    .senjin-item.mx-auto
      .api-img
        = link_to item.item_url do
          = image_tag item.image_urls
      .api-content
        = item.item_name
        .api
          .api-title
            購入金額
          .api-value
            #{item.item_price}円
        .api
          .api-title 
            平均評価
          .api-value
            #{item.review_average}
        .buy-list.mt-2
      - if current_user.has_buylist?(item)
        .not-buy#unfollow-btn
          = link_to '購入リストから解除', rakuten_buylist_path(item), method: 'delete',class: 'rakuten-delete'
      - else
        .buy#follow-btn
          = link_to '購入リストに登録', rakuten_buylist_path(item), method: 'post',class: 'rakuten-post'

完成イメージ

スクリーンショット 2021-04-06 13.07.50.png

以上でざっくりですが説明を終わらせていただきます。
何かご質問や不備な点などあればコメントいただきたいです

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4