【Rails】楽天APIを使った商品検索をAjax(ページ遷移なし)で実装する( Amazon APIでも応用可 )

【Rails】楽天APIを使った商品検索をAjax(ページ遷移なし)で実装する( Amazon APIでも応用可 ):

今日はRailsのお話です。

楽天APIを使って Ajax(非同期通信)でページ遷移することなく商品の検索結果を表示する という機能を実装してみようと思います。

AmazonAPIを使いたいという方でもデータの引っ張り方が違うだけなのでほぼ変わりません。


理想とする動きはこちらです。



Ajax.gif


ページ遷移することなく楽天市場の検索結果が表示されていますね!

(デザインは好きなように変更してください^^;)

2番目の「ハローキティ お金遊びセット」が気になるところですが話を進めます。

この機能を実装するためにはいくつか方法が考えられます。

例えば、jQueryでajax処理をそのまま書いて楽天APIからデータを引っ張ってくることができそうです。

$.ajax({ 
  type: 'get', 
  url: 'https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706?', 
  data: { 
    applicationId: "ここにアプリケーションIDを書く",  
    keyword: keyword, 
  } 
機能としてはこれでも動きます。しかし,jQueryでapplicationIdをそのまま書いてしまうと開発者ツールを使って誰でもapplicationIdを確認することができます。

まずいですね^^;

そこで今回はRailsに用意されているremote: trueという機能を使ってAjax処理を簡単に行いましょう.

(Railsに感謝^^)


楽天APIの導入まで (飛ばしてok)

楽天会員に登録、ログインしてからアプリ新規作成フォームからアプリIDを発行してください。

新規アプリ作成ボタンを押すと

  • アプリケーションID
  • アフィリエイトID
などが発行されます。

このアプリケーションIDは悪用されるとまずいので誰にも見せないようにしましょう。さっきのjQueryを使ったAjax処理ではここが丸見えだったということです。

次に使用するgemを追加します。Gemfileに以下の記述を追加してbundle installしましょう。

Gemfile
gem 'rakuten_web_service' 
gem 'dotenv-rails' 
rakuten_web_serviceは楽天APIを扱うためのGem、dotenv-railsは環境変数を簡単に扱うためのGemです(単純にアプリケーションIDを隠すために必要だと思っておいても大丈夫です)。

config/initializersのディレクトリに名前は何でもいいので .rb ファイルを作りましょう。

config/initializers/rakuten_api.rb
RakutenWebService.configure do |c| 
  c.application_id = ENV['Rakuten_API_KEY'] 
end 
今回はrakuten_api.rbというファイルを作りました。

次に代入する環境変数を設定します。

Gemfileと同じ階層に.envというファイルを作ってください。

.env
Rakuten_API_KEY=0123456789123456789 #自分のアプリIDを入れてください。 
ここでは仮に0123456789123456789としています。

.envで環境変数を設定してinitializers以下の作成したファイルでENV['Rakuten_API_KEY']として代入することができました。環境変数はENV['環境変数']と書いて取り出すことができます。気になる人はコンソールでENV['Rakuten_API_KEY']と書いてみましょう。

あとバージョンをgitで管理する人は.envをgitignoreするのを忘れないようにしましょう。

.gitignore
.env #追加しておく 
これでアプリIDを隠すことができました。(Railsに感謝^^)

ここまでで楽天APIを使う準備が整いました.


Ajax処理を書いていこう

今回はできるだけシンプルに記述してみます。動くはずですがテストはしてないので、動かねえよ!と気づいた方は教えてください^^; ここではデータの保存はしないのでModelは作ってません。


まずはルーティング

route.rb
Rails.application.routes.draw do 
  root to: 'toppages#index' 
  get 'toppages_search' => 'toppagse#search' 
end 
Toppagesコントローラーのindexアクションから呼ばれるindex.html.erbがrootとして表示されるようにしました。そしてtoppages_searchに get が送られるとToppagesコントローラーのsearchアクションが呼ばれるようにルーティングを設定しました。

(Toppagesコントローラーは予め作っておいたものです。rails g controllerコマンドで作れます^^;)


Viewをみていこう

index.html.erb
  <%= form_tag :toppages_search, method: :get, remote: true do -%> 
  <%= label_tag :keyword, 'キーワード検索'%> 
  <%= text_field_tag 'keyword', params[:keyword] %> 
  <%= submit_tag('Ajaxで検索結果を表示') %> 
  <% end %> 
 
# ▽▽▽ここに返ってくる商品情報を入れるよ▽▽▽ 
  <div id="Remote"></div> 
form_tag を使って商品検索のための検索フォームを作っています。

このフォーム<%= form_tag :toppages_search, method: :get, remote: true do -%>では<%= submit_tag %>が押された時にtoppagesコントローラーのsearchアクションに get を送ることを設定しています。メソッドをgetに指定しないとpostになるので注意です。

ここで重要なのがremote: trueを書いてあげることです。
remote: trueを書くことで次に呼び出すリクエストがhtmlファイルからjsファイルに変わります。(説明が難しい^^;;)

つまりAjax処理が簡単に行えるわけです。

通常であればフォームのsubmitボタンが押されればそれに対応したコントローラーのアクションからhtml.erbなどのviewファイルがrender(呼び出し)され ページ遷移して 表示されます。

それがremote: trueを書くだけでhtml.erbではなくjs.erbなどのjsファイルが呼び出しされるようになります。jsファイルであればDOM操作して ページ遷移することなく viewの表示を変えれそうです。


コントローラーでの処理

続いてコントローラーです。

toppages_controller.rb
class ToppagesController < ApplicationController 
 
  def index 
  end 
 
  def search 
    @keyword = params[:keyword] 
  #送られてきたキーワードが空ではないか確認してして、大丈夫ならajax_hatsudoメソッドを呼び出します。 
    ajax_hatsudo if @keyword.present?  
  end 
 
  #呼び出されるajax_hatsudoメソッドです。 
  def ajax_hatsudo 
  #楽天APIから検索キーワードでヒットした商品を変数@itemsに入れてViewに渡してあげます。 
      @items = RakutenWebService::Ichiba::Item.search(keyword: params[:keyword]) 
  end 
 
end 
 
ほとんどの説明はコメントアウトでしてみました^^

はじめのViewではフォームから serachアクションremote:truegetのリクエスト を送っていました。
remote:trueがあるので 通常は search.html.erbが呼び出されるところが search.js.erb と変わります。

では呼び出されるsearch.js.erbをみていきましょう。


呼び出されるjsファイル

ここでしたい処理は検索フォームの設置されていた呼び出し元のView index.html.erb のDOM操作(JavaScriotでHTMLの要素を追加する)です。

search.js.erb
# ▽▽▽index.html.erbに用意しておいた<div id="Remote"></div>の中身を空にする(2回目以降の検索で前のデータを消したいため。)▽▽▽ 
$('#Remote').empty(); 
 
# コントローラーから渡された変数@itemsを処理する。js.erbなのでRubyのコードを使うことができる。ここでは@itemsに入っている初めの3つを取り出して処理する。 
<% @items.first(3).each do |item| %> 
 
  # idがRemoteのHTML要素の中に、新たな要素を追加 
  $('#Remote').append("<p><%= "#{item['itemName']}, #{item.price} yen" %></p>") 
 
<% end %> 
item['itemName']などは楽天APIでの決められたデータの取り出し方です。

これで無事にindex.html.erbのHTML要素を変更できました。

Ajax処理の完了です!


まとめ

お疲れさまでした^^

今回は楽天APIを使ってページ遷移なしで商品の検索結果を表示することができました。

これは初めにも言ったようにAmazon APIにも応用できそうですね。

remote: trueを使った処理は長すぎるフォームを分割して表示する時やページをまとめてスッキリさせたい時など様々応用できそうです。


どうでもいい世間話

最近、寒いですね。文系大学生の僕はただいま就活中です。これからもたまにQiitaに記事を投稿するのでよろしくお願いします^^

ありがとうございました。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)