はじめに
今回はTwitter APIを利用して、Rails5でツイッターのツイートを検索するアプリを作成します。
事前準備
実際にコードを書く前に何点か事前準備をします。
Consumer Keyの取得
Twitter APIを利用するために、まずは今回作成するアプリをTwitterに登録し、Consumer Keyを取得します。アプリケーションの登録は以下のURLから行います。
Consumer Keyの取得方法は細かく説明しませんが、一点だけ補足すると、WebsiteやCallback URLを記述する必要があるのですが、サンプルアプリとして利用するのであれば、http://0.0.0.0:3000/
で問題ありません。
なお今回はツイッターのツイートを検索するだけなので、ユーザー認証は必要ありません。ですので、アクセストークンについては取得する必要がありません。
プロジェクトの雛形の作成
まずはrails new
でプロジェクトを作成します。
$ rail new twitter-search
Twitter gemを利用するのでGemfileに以下を追記します。
gem 'twitter'
bundle
を実行し、gemをインストールします。
$ bundle
Rails generateのcontrollerオプションを使って、コントローラーとビューを作成します。
$ rails g controller tweets
モックの作成
次に、モックを作成します。
Routesの編集
今回は http://localhost:3000/tweets/search のURLに検索ページを作成するので、以下のようにルーティングを設定します。
Rails.application.routes.draw do
get "/tweets/search" => 'tweets#search'
end
Controllerの作成
ルーティングに対応するメソッド(search)を作成します。
class TweetsController < ApplicationController
def search
respond_to do |format|
format.html # show.html.erb
end
end
end
Viewの作成
searchメソッドによって呼ばれるビューを作成します。
今回は検索キーワードを送るだけの単純な検索窓を作成し、このフォームは何のモデルにも基づかないため、form_tag
、text_field_tag
を利用しています。[1][2]
なお、text_field_tag
にあるnil
はplaceholder
で指定している文字列をデフォルトで薄字で表示させるためのものです。[3]
<%= render partial: 'tweet_list' %>
の部分は実際に検索結果を表示するViewで、別のerbファイルから呼び出すようにします。(検索結果を表示するViewの作成は後述)
<div class='content'>
<div id="search-box">
<%= form_tag('/tweets/search', method: :get) do %>
<%= text_field_tag :tweet, nil, id: "tweet_search", name: "keyword", placeholder: "キーワードを打ち込んでください", style: "width: 200px;"%><button title="検索" type="submit">検索</button>
<% end %>
</div>
<div id='tweet_list'>
<%= render partial: 'tweet_list' %>
</div>
</div>
モックの検証
サーバーを起動して正しく画面が表示されているか検証していきます。
$ rails s
http://localhost:3000/tweets/search にアクセスすると以下のような画面が表示されると思います。
Twitterのツイートを取得する機能の作成
上記で画面は作成できたので、実際にツイート検索と取得を行う機能を作成していきます。
Modelの作成
検索したツイートを格納させるためのモデルを作成します。
今回のモデルはDBへのアクセスが必要ないので[4]、以下のようになります。
class Tweet
# プロパティの設定
attr_accessor :contents
def initialize(contents)
@contents = contents
end
end
Controllerの編集
Controllerは以下のようになります。
class TweetsController < ApplicationController
def search
client = Twitter::REST::Client.new do |config|
# 事前準備で取得したキーのセット
config.consumer_key = "xxxxxxxxxxxxxxxxxxxxxxx"
config.consumer_secret = "yyyyyyyyyyyyyyyyyyyyyyyyyyyy"
end
@tweets = []
since_id = nil
# 検索ワードが存在していたらツイートを取得
if params[:keyword].present?
# リツイートを除く、検索ワードにひっかかった最新10件のツイートを取得する
tweets = client.search(params[:keyword], count: 10, result_type: "recent", exclude: "retweets", since_id: since_id)
# 取得したツイートをモデルに渡す
tweets.take(10).each do |tw|
tweet = Tweet.new(tw.full_text)
@tweets << tweet
end
end
respond_to do |format|
format.html # show.html.erb
format.json { render json: @tweets } # jsonを指定した場合、jsonフォーマットで返す
end
end
end
Consumer(API) Keyのリファクタリング
上記のように直接ControllerにConsumer Keyを記述してもいいのですが、Railsの場合、アクセスキーなどはsecret.yml
に書いておいたほうがセキュリティ的に良いです。[5]
ですので、以下のようにsecret.yml
の新規作成と、tweets_controller.rb
の編集を行います。
default: &default
twitter_consumer_key: "xxxxxxxxxxxxxxxxxxxxxxx"
twitter_consumer_secret: "yyyyyyyyyyyyyyyyyyyyyyyyyyyy"
development:
<<: *default
test:
<<: *default
production:
twitter_consumer_key: <%= ENV["TWITTER_CONSUMER_KEY"] %>
twitter_consumer_secret: <%= ENV["TWITTER_CONSUMER_SECRET"] %>
def search
client = Twitter::REST::Client.new do |config|
- config.consumer_key = "xxxxxxxxxxxxxxxxxxxxxxx"
- config.consumer_secret = "yyyyyyyyyyyyyyyyyyyyyyyyyyyy"
+ config.consumer_key = Rails.application.secrets.twitter_consumer_key
+ config.consumer_secret = Rails.application.secrets.twitter_consumer_secret
end
検索結果を表示するViewの追加
search.html.erb
から呼ばれる検索結果を表示するViewを作成していきます。
コントローラーで@tweets
に検索結果のツイートが格納されたものをループで一件づつ表示させています。
<% if @tweets.present? %>
<h2>検索結果</h2>
<ul>
<% @tweets.each_with_index do |tweet, i| %>
<div class="list">
<li>Tweet<%= i %>: <%= tweet.contents %> </li>
</div>
<% end %>
</ul>
<% end %>
アプリの検証
サーバーを起動して正しくツイート検索ができるか検証していきます。
$ rails s
http://localhost:3000/tweets/search にアクセスして実際に検索ワードを入れて結果が表示されるか確認してみてください。
以下は「正月」というキーワードで検索した結果です。
json形式のデータが欲しい場合はエンドポイントを.json
と指定します。
例えば「正月」というキーワードで検索したい場合のリクストURIは以下のようになります。
参考
[1] [Rails3] form_for と form_tag、text_field と text_field_tag の違い
[2] 【Rails】form_for/form_tagの違い・使い分けをまとめた
[3] text_field_tag
[4] 【Rails】Amazon APIで書籍検索アプリ作成
[5] Rails環境でTwitterとFacebookを使ってサイトの拡散をするため自動投稿させるアプリを作成してみた