【Ruby on Rails】楽天APIで商品検索アプリを作る

##プロジェクトを開始

```
rails new raktuensearch
```

##データベースと接続

```
cd rakutensearch
rails db:create
```

サーバーを起動して動作確認

```
rails s
```
“Yay! You’re on Rails!” の表示を確認できたらOK

##共通レイアウト

###共通のView

```ruby:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html lang="ja">
  <head>
    <title>WishlistTest</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css">

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"></script>
  </head>

  <body data-turbolinks="false">
    <%= render 'layouts/navbar' %>

    <div class="container">
      <%= render 'layouts/flash_messages' %>

      <%= yield %>
    </div>
  </body>
</html>
```

###フラッシュメッセージ

```ruby:app/views/layouts/_flash_messages.html.erb
<% flash.each do |message_type, message| %>
  <div class="alert alert-<%= message_type %>"><%= message %></div>
<% end %>
```

###エラーメッセージ

```ruby:app/views/layouts/_error_messages.html.erb
<% if model.errors.any? %>
  <div id="error_explanation" class="alert alert-warning">
    <ul class="mb-0">
      <% model.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>
```

###ナビバー

```ruby:app/views/layouts/_navbar.html.erb
<header class="mb-4">
  <nav class="navbar navbar-expand-sm navbar-dark bg-dark">
    <div class="container-fluid ps-5 pe-5">
      <a class="navbar-brand" href="/">Microposts</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent">
        <span class="navbar-toggler-icon"></span>
      </button>

      <div class="collapse navbar-collapse justify-content-end" id="navbarSupportedContent">
        <ul class="navbar-nav">
          <li class="nav-item"><a href="#" class="nav-link">Signup</a></li>
          <li class="nav-item"><a href="#" class="nav-link">Login</a></li>
        </ul>
      </div>
    </div>
  </nav>
</header>
```

##【楽天API】gemをインストール

```
gem 'rakuten_web_service'
gem 'dotenv-rails'
```

1行目は楽天APIを利用するため、2行目はdotenvを利用するために記述

```
bundle install
```
Gemfileに追記したので`bundle install`

##【楽天API】アプリケーションIDを設定

###取得したアプリケーションIDを設定
取得したアプリケーションIDを設定するため`config/initializers`フォルダの中に`rauten.rb`ファイルを作成し、以下を記述する

```ruby:rakuten.rb
RakutenWebService.configure do |c|
  # (必須) アプリケーションID
  c.application_id = ENV['RWS_APPLICATION_ID']

  # (任意) 楽天アフィリエイトID
  c.affiliate_id = ENV['RWS_AFFILIATION_ID']

end
```
アフィリエイトIDの記述は任意なので不必要な人は記述しなくてもよい

```ruby:
touch .env
```
環境変数を定義するため`.env`ファイルを作成し以下を記述

```ruby:.env
RWS_APPLICATION_ID=取得したアプリケーションID
```


##ControllerとViewファイルを作成

```
rails g controller items search
```

###Controllerの確認

```ruby:app/controllers/items_controller.rb
class ItemsController < ApplicationController
  def search
  end
end
```
`search`アクションが記述されていることを確認。とりあえずこのままにしておく

##Router
トップページに検索画面と検索結果（製品一覧）が表示されるようルーティング

```ruby:routes.rb
Rails.application.routes.draw do
    get 'items/search'
end
```

##Viewの作成
Viewファイル`search.html`に以下を記述

```ruby:app/views/items/search.html.erb
<h1>製品名を入力して検索</h1>
<div class="search-box">
    <%= form_with url: items_search_path, method: :get, local: true do |f| %>
    <div class="form-group">
        <%= f.text_field :keyword, value: params[:keyword], class: "form-control" %>
        <%= f.submit '製品名を検索', class: "form-control btn btn-success" %>
    </div>
    <% end %>
<% if @items.present? %>
  <%= render 'items/item' %>
<% end %>
</div>
```

パーシャルファイル`_item.html.erb`を`app/views/items`直下に作成し以下を記述

```ruby:app/views/items/_item.html.erb
<% @items.first(10).each do |item| %>
<div class="list-group">
 <%= image_tag (item['smallImageUrls'][0]) %>
 <%= link_to item.name, "#{item.url}" %>
 <%= number_with_delimiter(item.price) %>円
</div>
<% end %>
```

Viewファイルは以上

##Controllerの作成

```ruby:app/controllers/items_controller.rb
class ItemsController < ApplicationController
  def search
    if params[:keyword]
      @items = RakutenWebService::Ichiba::Item.search(keyword: params[:keyword])
    end
  end
end
```

ここでの`RakutenWebService::Ichiba::Item.search(keyword: params[:keyword])`がこの記事で最も重要なところで、入力した値`params[:keyword]`を引数として`search`メソッドで検索をかけ、ヒットしたものを`@items`に格納し、一覧表示させている
当記事では楽天市場内での商品を検索したかったので`RakutenWebService::Ichiba::Item.search`としているが、例えば楽天ブックス内で検索したいなら`RakutenWebService::Books::Book.search`と記述すればよい
詳しくは公式ページに記載されているので参考にしてほしい

https://webservice.rakuten.co.jp/document/