#はじめに
ポートフォリオ等でwebアプリを開発していると、「外部APIを利用してみたい」という方もいるかと思います。
今回紹介する楽天APIに関しては、データを取得すること自体は、そんなに難しくありません。
アプリIDを取得してgemをインストールすれば、割と簡単にデータを取得することができます。
ただし、「APIのデータをテーブルに格納して他のテーブルと関連付けて…」というように、取得したデータをアプリ内で活用しようとするとやや難易度が上がります(個人的な考えですが笑)
本記事では「取得したデータをテーブルに格納する方法」と「アソシエーションの設定」について記載していきます。
また、最後にアプリ内で検索機能を設けて、必要なデータを表示させるコードも簡単に記載しました。
これから楽天APIを使ってみたいという方の参考になれば幸いです。
#注意
-
本記事は楽天APIについて言及しております。
また楽天APIにも様々ありますが、今回は楽天ブックス書籍検索APIを用います。 -
本記事では、APIのデータ取得の部分(アプリIDの取得とgemのインストール)は割愛します。
データ取得部分については、以下の記事を参考にしてみてください。
https://freesworder.net/rakuten-api-rails/
https://qiita.com/hakusai_it/items/6453c4577647cb8995d3
#環境
- Ruby version 2.7.2
- Rails version 6.0.3.4
#ER図
今回は以下のER図にて、話を進めていきます。
Bookテーブルがデータを格納するテーブルです。
取得した本について、レビューを記載するために、Reviewテーブルを設けています。
Bookテーブルのカラムについて少し説明します。
今回Bookテーブルのprimary_keyは『id』ではなく、商品の固有の番号である『isbn』を使っていきます。
『title』,『author』はそれぞれ、本のタイトルと著者名です。
『item_caption』は商品の説明、『item_url』は楽天の商品のurl、『middleimage_url』は本の画像です。
その他にも様々なデータがありますので、気になる方は以下のURLを参考にしてください。
https://webservice.rakuten.co.jp/api/booksbooksearch/
#実装工程
##概要
以下のような流れで実装していきます。
step1. テーブルの作成
step2. アソシエーションの設定
step3. ルーティングの設定
step4. コントローラーの設定
step5. 検索ページの作成
「アソシエーションの設定」はstep1・step2、
「取得したデータをテーブルに格納」はstep3・step4、
「検索ページの実装」はstep5で実装します
##step1. テーブルの作成
各テーブルを作成していきます。
前述の通り、今回は User, Book, Reviewテーブルを作っていきます。
####Userテーブル作成
Userテーブルは特に変わったことはしません。
モデルを作成して、マイグレーションを実行していきましょう!
$ rails g model User name:string email:string password_digest:string
$ rails g db:migrate
####Bookテーブル作成
まずはモデルを作成していきます。
$ rails g model Book title:string author:string isbn:bigint url:string image_url:string
次にmigrationファイルを書き換えていきます。
Bookテーブルのprimary_keyは『id』ではなく、商品の固有の番号である『isbn』を使っていくため、ファイルの書き換えが必要になります。
ファイル名の米印にはMigration ID(日付等が書いてある数字)が入ります。
ActiveRecord::Migration[6.0]の部分は人によって異なると思います。
isbn部分にnull: false, primary_key: true
を追記します。
class CreateBooks < ActiveRecord::Migration[6.0]
def change
create_table :books, id: false do |t|
t.string :title
t.string :author
t.bigint :isbn, null: false, primary_key: true
t.string :url
t.string :image_url
t.timestamps
end
end
end
マイグレーションファイルを書き換えたらマイグレーションしていきます。
$ rails g db:migrate
####Reviewテーブル作成
最後にReviewテーブルを作成していきます。
$ rails g model Review content:string user:references book:references
次にmigrationファイルを書き換えていきます。
ファイル名の米印にはMigration ID(日付等が書いてある数字)が入ります。
ActiveRecord::Migration[6.0]の部分は人によって異なると思います。
class CreateReviews < ActiveRecord::Migration[6.0]
def change
create_table :books, id: false do |t|
#bookの部分に記載してあったforeign_key: trueを削除する
t.references :book, null: false
t.references :user, null: false, foreign_key: true
t.timestamps
end
#この部分の新たに以下のコードを記載
add_foreign_key :bookcases, :books, column: :book_id , primary_key: :isbn
end
end
マイグレーションファイルを書き換えたらマイグレーションを実行していきます。
$ rails g db:migrate
これでテーブルの作成は以上です。
次はアソシエーションの設定です。
##step2. アソシエーションの設定
各model.rbのアソシエーションを設定してきます。
ここでもBookテーブルのprimary_keyを『isbn』になるようコードを書いていきます。
class User < ApplicationRecord
has_many :reviews, dependent: :destroy
end
class Book < ApplicationRecord
self.primary_key = "isbn"
has_many :reviews, dependent: :destroy
end
class Bookcase < ApplicationRecord
belongs_to :user
belongs_to :book, primary_key: "isbn"
end
step2までで、テーブル作成とアソシエーションの設定は終了です。
step3以降はBookテーブルにデータを格納する方法を主に説明していきますので、User, Reviewモデルについては割愛し、Bookモデルについてのみ記載していきます。
##step3. ルーティングの設定
今回は検索欄と検索結果を表示するために/searchアクションを設けています。
必要であれば、ご自身で追加のアクションを設定してください。
get 'books/search', to: "books#search"
###step4. コントローラの設定
まずはコントローラファイルを作成していきます。
$ rails g controller books
作成したコントローラファイルに以下のコードを記載していきます。
class BooksController < ApplicationController
def search
#ここで空の配列を作ります
@books = []
@title = params[:title]
if @title.present?
#この部分でresultsに楽天APIから取得したデータ(jsonデータ)を格納します。
#今回は書籍のタイトルを検索して、一致するデータを格納するように設定しています。
results = RakutenWebService::Books::Book.search({
title: @title,
})
#この部分で「@books」にAPIからの取得したJSONデータを格納していきます。
#read(result)については、privateメソッドとして、設定しております。
results.each do |result|
book = Book.new(read(result))
@books << book
end
end
#「@books」内の各データをそれぞれ保存していきます。
#すでに保存済の本は除外するためにunlessの構文を記載しています。
@books.each do |book|
unless Book.all.include?(book)
book.save
end
end
end
private
#「楽天APIのデータから必要なデータを絞り込む」、且つ「対応するカラムにデータを格納する」メソッドを設定していきます。
def read(result)
title = result["title"]
author = result["author"]
url = result["itemUrl"]
isbn = result["isbn"]
image_url = result["mediumImageUrl"].gsub('?_ex=120x120', '')
book_genre_id = result["booksGenreId"]
item_caption = result["itemCaption"]
{
title: title,
author: author,
url: url,
isbn: isbn,
image_url: image_url,
book_genre_id: book_genre_id,
item_caption: item_caption
}
end
end
step4までで、テーブルへのデータ格納は実装完了です。
step5では検索ページと結果の出力ページを作成していきます。
###step5. 検索ページの作成
search.html.erbというファイルを作成し、コードを書いていきます。
※本記事では最低限のコードのみ記載しております。適宜classを設定し、見た目を改善しましょう!
#検索バーを表示
<%= form_tag(books_search_path, method: :get) do %>
<%= text_field_tag :title, @title %>
<%= button_tag type: "submit" %>
<% end %>
#検索結果を表示
<% if @books %>
<% @books.each do |book| %>
#ご自身が表示させたいデータを記載してください。
#以下のコードではは画像、タイトル、著者名、商品の説明を表示させています。
<%= image_tag book.image_url %>
<%= book.title %>
<%= book.author %>
<%= book.item_caption %>
<% end %>
<% end %>
以上で実装工程は終了となります。
何かご不明点や誤っている点がございましたら、コメントにて教えていただけると幸いです。