プログラミング備忘録

プログラミングの学習状況をメモしています

82日目

今日の学習

Ruby on Rails

楽天APIの検索結果をDBに保存する

やり方がなかなか分からず何日もかかってしまった。

今日ふとできるようになったが、根本的に何が駄目だったのかは分からないままなのでちょっと不安になった。

記録用に自分のコードを残しておこうと思う。

●ログインしているユーザーが本の検索をする→好きな本を選択して自分のDBに保存する deviseというgemを利用。

楽天APIのデータをテーブルに格納する方法 - Qiita

楽天ブックス書籍検索APIで検索した商品の一つをDBに保存する - Qiita

参考にさせていただいた記事。

ほぼこちらの記事にある通りに行なった。

本を保存するitemsコントローラ

class ItemsController < ApplicationController
  def index
    @items = current_user.items
  end

  def new
    @items = []

    @title = params[:title]
    if @title.present?
      results = RakutenWebService::Books::Book.search({
                                                        title: @title
                                                      })

      results.each do |result|
        item = Item.new(read(result))
        @items << item
      end
    end
  end

  def create
    @item = Item.find_or_initialize_by(isbn: params[:isbn])

    unless @item.persisted?
      results = RakutenWebService::Books::Book.search(isbn: @item.isbn)
      current_user.items.create!(read(results.first))
    end
  end

  private

  def item_params
    params.require(:item).permit(:title, :isbn, :item_url, :image_url)
  end

  def read(result)
    title = result['title']
    isbn = result['isbn']
    item_url = result['itemUrl']
    image_url = result['mediumImageUrl'].gsub('?_ex=120x120', '')

    {
      title: title,
      isbn: isbn,
      item_url: item_url,
      image_url: image_url
    }
  end
end

createメソッドの部分でだいぶ苦戦してしまった。

viewファイル

<%= form_with method: :get, local: true do |f| %>
  <%= f.text_field :title, placholder: "書籍タイトル" %>
  <%= f.submit "検索する" %>
<% end %>

<% if @items %>
  <% @items.each do |item| %>
    <p><%= item.title %></p>
    <p><%= image_tag item.image_url, size: 250 %></p>
      <%= form_with model: @item, local: true do |f| %>
        <%= f.hidden_field :isbn, :value => item.isbn %>
        <%= f.submit "本を保存する" %>
      <% end %>
  <% end %>
<% end %>

参考にした記事ではform_tagが使われていたので、form_withでも機能するように書き直してみた。蛇足な部分があるかもしれない。

個別にコードを見る。まず、検索ボックスを用意している部分。

<%= form_with method: :get, local: true do |f| %>
  <%= f.text_field :title, placholder: "書籍タイトル" %>
  <%= f.submit "検索する" %>
<% end %>

ここで入力されたtitlenewメソッドで使われる。

newメソッドでは、受け取ったtitleを利用して楽天APIのBookサーチで検索された結果郡を@itemsという配列に入れてくれる。

次に、if文を使ってもしも配列に一つでも情報が入っていればそのまま検索結果を表示するようにする。

<% if @items %>
  <% @items.each do |item| %>
    <p><%= item.title %></p>
    <p><%= image_tag item.image_url, size: 250 %></p>
  <% end %>
<% end %>

ひとまず、ヒットした本のタイトルと、画像を表示するようにしておいた。サイズは適当。

この検索結果に、以下を付け加えることでDBに保存するためのボタンを設置する。

<%= form_with model: @item, local: true do |f| %>
    <%= f.hidden_field :isbn, :value => item.isbn %>
    <%= f.submit "本を保存する" %>
<% end %>

isbnという楽天ブックスで扱われている一意の情報を利用することで、コントローラ側でもう一度isbnを検索してもらい、該当するisbnの商品をDBに保存するという仕組みになっている。

やっと一歩前進できたので、このまま頑張りたい。