【Rails TMDB】APIで映画情報を取得しよう
警告
だいぶ昔に書いた記事なので、現時点ではエラーや動作がしないなどの事象が起こる可能性があります泣
ちゃんと書き直すので少々お待ちを!!
取り急ぎ、問題があれば、twitter( https://twitter.com/kazuhitonakayam )までご連絡ください🙏
なぜこの記事を僕が書くのか
端的に、Railsを用いてAPI経由で映画情報を取得できるようになる、参考記事がなかったから。
この記事のゴール
TMDBのAPIを用いて世界範囲で映画情報を取得し、そのデータを自分のオリジナルサービスで扱えるようになる。
この記事で扱わないこと
・APIとは何か
・TMDBのAPIで、映画以外の情報を取得する方法
そもそもTMDBとは
The Movie Database (TMDb) is a community built movie and TV database. Every piece of data has been added by our amazing community dating back to 2008.
映画データベース(TMDb)は、コミュニティで構築された映画およびTVデータベースです。すべてのデータは、2008年にさかのぼる私たちの素晴らしいコミュニティによって追加されました。
とのことです!コミュティ型で成長させてきたプロダクトのようですね
だからなのか、結構APIも容易に取得できました
TMDBに登録(サインアップ)& API取得
APIの登録の時に、プロダクトのURLが必要なので、Railsアプリはリリースしておいてくださいね(^○^)/
(厳密にいくと、別にリリースする必要はないのですが、リリースしておいた方がスムーズなので今回は、リリースしてる前提で進めていきます!)※リリースしたい方
この記事を参考に、TMDBに開発者用のAPIの使用許可を得ましょう!
themoviedb-apiというGemをインストール
こちらから、themoviedb-apiというGemの情報をご覧ください!
Provides a simple and intuitive interface for the Movie Database API making use of OpenStruct.
何やら直感的なインターフェイスを提供してくれるそう笑。
開発者の方、感謝します
OpenStructとは
→OpenStructは、要素を動的に追加・削除できる手軽な構造体を提供する、rubyの標準ライブラリ。
例としてはこんな感じ。
require 'ostruct'
# 構造体を作って動的にpropertyを追加
son = OpenStruct.new
son.name = "Thomas"
son.age = 3
わかんない笑
一旦先に進みましょう
んじゃあ早速インストール
#(省略) 以下の1行をGemfileの最後に書きましょう!
gem 'themoviedb-api', '~> 1.3'
> bundle install --without production # 別にbundle installだけでも良いです
これで、TMDBを利用するために必要な、直感的なインターフェイスを提供してくれるGemはインストールできた。
自分のAPIを自分のアプリに記述する
自分の場合、movies_controllerを作成し、searchアクション、並びにshowアクションを用意しました。
モデルは、映画情報を引っ張ってくるだけの範囲ならば、こちらの方でモデルの作成は不要です。
> rails g controller movies search show
class MoviesController < ApplicationController
require 'themoviedb-api'
Tmdb::Api.key("ご自身のAPI Key")
Tmdb::Api.language("ja") # こちらで映画情報の表示の際の言語設定を日本語にできます
def search
end
def show
end
end
一旦、この辺で、これらの変更を本番環境にあげましょうか
> git add .
> git commit -m "commit"
> git push heroku master #masterで打ってできなかったらmainで打ってみてくださいな
現時点で何ができるか
ここまでできると、自分のターミナル上で、映画情報が取得できます
> heroku run rails console
#対話モードになる
> Tmdb::Search.movie("Harry")
#Tmdb::Search.movie()で、()に書いた文字列で映画情報を検索できる。
上のコマンドでこのようなアウトプットが出ます
先ほど書きましたが、このアウトプットはOpenStructというRubyライブラリによって、OpenStruct型で出力されていて、馴染みが僕にはなかったので、いったんjson形式に変換します。
to_jsonによって、実現しています。
(Tmdb::Search.movie("Harry")).to_json #まだターミナルに打たないでね
次に、JSON.parse
を用いて、与えられた JSON 形式の文字列を Ruby オブジェクトに変換して返します。
JSON.parse((Tmdb::Search.movie('Harry')).to_json)
After
分かりますでしょうか
データの対応関係がわかりやすくなってたでしょう
最後に、さらにこれをみやすくするために、
JSON.pretty_generate
メソッドを使ってみやすくします
# 一旦moviedataという変数にアウトプットを格納
> moviedata = JSON.parse((Tmdb::Search.movie("Harry")).to_json)
# そして
> puts JSON.pretty_generate(moviedata)
これによってアウトプットが劇的に見易くなります泣
データのまとまりが視覚的によくわかりますね。
最終的にはjson形式でデータが整形されましたね笑
自分的にはjson形式が一番分かりやすかったのでこうしました!
もっと効率的な方法があれば教えてくださいね笑
あとはViewにアウトプットを表示するだけ
さて終盤です。
ポイントはjson形式のデータの取り出し方ですね
この記事をご覧になればわかると思います👍
例えば以下のアウトプットから、映画のタイトルの情報を取得したいならば、
moviedata['table']['results'][0]['table']['title']
これを参考にViewを作っていきましょう!
仕様としては、
・検索バーに検索したい映画を入力すれば、目的の映画情報が取得、表示できる
・検索してない時(アプリに最初アクセスする時)には、人気映画を取得、表示する
というものです!
<h1>映画検索</h1>
<div>
<%= form_tag(root_path, method: :get) do %>
<%= search_field_tag :looking_for, nil, placeholder: 'Movie Title...' %>
<%= submit_tag '検索' %>
<% end %>
</div>
<%# 検索された時にコンテンツを表示する %>
<%if params[:looking_for].present? %>
<% movieinfo = JSON.parse((Tmdb::Search.movie(params[:looking_for])).to_json) %>
<h2><%= params[:looking_for] %>の検索結果</h2>
=====================
<% i = 0 %>
<div class="card-wrapper">
<% while i < movieinfo['table']['results'].count %>
<div class="card">
<div class="card-upperinfo">
<%if movieinfo['table']['results'][i]['table']['title'].present?%>
<h3><%= link_to movieinfo['table']['results'][i]['table']['title'],detail_path(movieinfo['table']['results'][i]['table']['id']) %></h3>
<%end%>
<% if movieinfo['table']['results'][i]['table']['release_date'].present? %>
<p class="release-date"><%= movieinfo['table']['results'][i]['table']['release_date'] %></p>
<%end%>
</div>
<% if movieinfo['table']['results'][i]['table']['poster_path'].present? %>
<p><%= image_tag 'https://image.tmdb.org/t/p/w1280' + movieinfo['table']['results'][i]['table']['poster_path'],class: "card-img" %></p>
<%end%>
</div>
<% i += 1%>
<%end%>
</div>
<%else%>
<%# 検索されていない時にトレンドコンテンツを表示する %>
<h2>本日の世界のトレンド</h2>
====================
<% movieinfo = JSON.parse((Tmdb::Movie.popular).to_json) %>
<% i = 0 %>
<div class="card-wrapper">
<% while i < movieinfo['table']['results'].count %>
<div class="card">
<div class="card-upperinfo">
<%if movieinfo['table']['results'][i]['table']['title'].present?%>
<h3><%= link_to movieinfo['table']['results'][i]['table']['title'], detail_path(movieinfo['table']['results'][i]['table']['id'])%></h3>
<%end%>
<% if movieinfo['table']['results'][i]['table']['release_date'].present? %>
<p class="release-date"><%= movieinfo['table']['results'][i]['table']['release_date'] %></p>
<%end%>
</div>
<% if movieinfo['table']['results'][i]['table']['poster_path'].present? %>
<p><%= image_tag 'https://image.tmdb.org/t/p/w1280' + movieinfo['table']['results'][i]['table']['poster_path'],class: "card-img" %></p>
<%end%>
</div>
<% i += 1%>
<%end%>
</div>
<%end%>
CSSは、参考程度に記しておきますね
.card {
// box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.5);
border-radius: 10px;
width: 28%;
margin-bottom: 100px;
padding: 20px;
box-sizing: border-box;
}
.card-wrapper {
width: 80%;
margin: auto;
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
}
.release-date {
text-align: right;
}
.card-img {
width: 100%;
border-radius: 16px;
}
.card-upperinfo {
height: 139px;
overflow-y: scroll;
}
今回は、
・検索したい映画情報で映画情報を取得するのに、
Tmdb::Search.movie()
・世界のトレンド映画情報を取得する際に、
Tmdb::Movie.popular
を使いましたが他にも様々な魔法があるので、ぜひ以下よりご覧ください!
htemoviedb-api Githubレポジトリ
できなかったりエラーが出たりしたらいつでもご連絡ください🙇♂️
Twitter
Github