【Rails】ActiveResourceを使用してYouTube動画を取得する
今回は「ActiveResource」を使って、YouTubeAPIを通しての画像取得にトライしました。
入力された検索ワードを使って検索し、引っかかった動画の情報を取得し表示したいためです。
ActiveResourceとは
RailsでActiveRecordを使用していると、Model経由でDBのデータを取得したり更新したりできますが、
ActiveResourceを使用すると、WebApiで取得してきたデータもModel経由で取得できるようにできます!
ViewやcontrollerからはDBとかAPIとかどこから取得してきたかを意識することなく、
同じようにModelからデータを操作することができます。
Railsデフォルトの機能ですね。
〜参考にさせて頂きました!〜
ActiveResource の使い方(前編) : Rails 同士で通信する - WebOS Goodies
ActiveResource::Base
YouTubeモデルの作成
コンソールから
Rails g model youtube
みたいなのを実行してYouTubeモデルを作成したら、
継承するクラスを「ActiveRecord」から「ActiveResource」に変更します。
class Youtube < ActiveResource::Base #ここ end
で、そのクラスの中に基本設定と取得ロジックを作成します。
class Youtube < ActiveResource::Base self.site = "http://gdata.youtube.com" def self.videos(search_word) self.find(:one, from: "/feeds/api/videos", params: { q: search_word , :"max-results" => 10, alt: "json"} ) end end
site
まずsite変数に取得先のサーバー名を指定します。
そしてvideosメソッドを作ってあげて、site.findでYouTubeから画像情報を取得するようにします。
findメソッド
引数一つ目ですが、idを渡すかシンボル:all,:first,lastを指定し取得するオブジェクトを指定します。
ただ今回のように引数2つ目の:fromでパスを直指定する場合、:oneという指定もできるらしい。
…ごめんなさい、ここに関しては私よくわかっていません(^_^;)
下記に説明があったのでもし良ければそちらの方を…
ActiveResource の使い方(前編) : Rails 同士で通信する - WebOS Goodies
今回は:oneじゃないとうまく行きませんでした。
指定したIDによって対応するオブジェクトが返却される、みたいなAPIじゃなく
指定したURIを叩くとjsonがまるごとドカンと返ってくるようなリクエストだから…???
paramsにはクエリパラメータをハッシュで渡せます。
以下を見ながら作成。
デベロッパー ガイド: Data API プロトコル - API クエリ パラメータ - YouTube — Google Developers
ある検索ワードで検索し、10件のデータをjsonで返却してくれというリクエストですね。
しかし、このままでは動きませんでした…
Formatクラスを修正
動かすと謎の"NameError”が発生。。
先輩が見つけてくれたのですが、どうやら返ってくるjsonデータに原因があるようで…
ActiveResourceは、返ってきたjsonデータの中身をModelのAttributeとして用意してくれます。
entryという項目があれば、モデル.entryとすればentryが取得できるわけです。
モデルの中にentryメソッドを作成してくれてるんですね。
…で、YoutubeAPIが返してくれる項目名の中に$が含まれるものがあったんですね。
Rubyではメソッド名の中に$を含むことはできませんから、NameErrorとなってしまったようです。
という訳で、jsonフォーマットを修正します。
class Youtube < ActiveResource::Base self.site = "http://gdata.youtube.com" # ↓追加 class Format include ActiveResource::Formats::JsonFormat def decode(json) super(json.gsub("$","_")) end end self.format = Format.new # ↑追加 def self.videos(search_word) self.find(:one, from: "/feeds/api/videos", params: { q: search_word , :"max-results" => 10, alt: "json"} ) end end
これで、jsonで取得した時には$を_に変更するようフォーマットが変更出来ました。
もし項目にhoge$entryのようなデータが含まれていた場合、
モデル.hoge_entryという形で取得できます。
これでとりあえず、youtubeモデルのvideosメソッドを叩けば
画像情報が取得できるようになりました!\(^o^)/
view側で取得したデータを煮るなり焼くなりしましょう。
やってみたサンプルソース
https://github.com/fumihiro/musician_search