hello-world
webエンジニアのメモ。とりあえずやってみる。

Rails4でTwitterStreamingAPIを使う その2

公開日時

Ruby2.0,Rails4で確認

前回: ハッシュタグがyoutubeとなっているtweetを取得してlogに表示する

というところまでやりました。

今回は

目標:取得したtweetをMongoDBに入れて簡単なAPIを作ってみる

ところまでやってみます。

MongoDBのインストール(mac homebrew)

  • brew install
brew install mongodb
  • 起動
mongod

Railsアプリケーション実装

mongoid初期設定

  • mongoid gem追加
# Gemfile

gem 'mongoid', git: 'git://github.com/mongoid/mongoid.git'
  • bundle install
./bin/bundle install
  • mongoid設定ファイルを生成
./bin/rails generate mongoid:config

ActiveRecordとMongoDBを共存させたかったので、 こちらの記事を参考にさせていただき設定しました。

  • defaultのormがActiveRecordになるように修正
# config/application.rb

module StreamingSample
  class Application < Rails::Application
    config.generators do |g|
      g.orm :active_record
    end
  end
end

Model作成

  • tweet収集用のMongoモデル作成
./bin/rails g mongoid:model tweet_mongo
  • Mongoモデルとしてロードするclassの設定
# config/mongoid.yml

development:
  options:
    preload_models:
      - tweet_mongo
  • TweetMongoモデル更新

dataにstreaming apiから取得したtweetをそのまま入れることにします

# app/model/tweet_mongo.rb

class TweetMongo
  include Mongoid::Document
  field :data
end

Tweet収集スクリプト修正

前回作成したTweet収集スクリプトでlogに出力していた部分をMongoDBに保存するように修正します。

また、前回のコードだとRails.rootにtwitter_streaming.pidとtwitter_streaming.outputが出力されていたのでDaemonのオプションを指定してtmp/pids以下にpidが保存されるように修正しました。

# script/twitter_streaming.rb

ENV["RAILS_ENV"] ||= "development"

root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
require File.join(root, "config", "environment")

daemon = TweetStream::Daemon.new('twitter_streaming',
                                 :log_output => false,
                                 :dir_mode => :script,
                                 :dir => File.join(Rails.root, 'tmp', 'pids'),
                                )

daemon.on_inited do
  ActiveRecord::Base.connection.disconnect!
  daemon_logger = Logger.new(File.join(Rails.root, "log", "stream.log"))
  Rails.logger = ActiveRecord::Base.logger = daemon_logger
  Rails.logger.debug "Listening..."
end
daemon.on_error do |message|
  Rails.logger.error message
end
daemon.track('#youtube') do |tweet|
  TweetMongo.create!(data: tweet.to_json) # MongoDBに保存する
end

Controller作成

取得したTweetをjsonとしてそのまま返す簡単なAPIを作ってみます。

  • api controller作成
./bin/rails g controller api::tweet
  • routing設定
# config/routes.rb

StreamingSample::Application.routes.draw do
  namespace 'api', :module => 'api' do
    get    'tweet'       => 'tweet#index'
  end
end
  • controller更新
# app/controllers/api/tweet_controller.rb

class Api::TweetController < ApplicationController
  def index
    tweets = TweetMongo.desc(:_id).limit(100).map {|tweet| JSON.parse(tweet.data)}
    render json: tweets
  end
end

ブラウザからアクセスしてみる

  • アプリ起動
./bin/rails s
  • ブラウザからアクセスしてみる

http://localhost:3000/api/tweet

これで最新順のTweetが最大100件表示されるAPIができました。

参考


Related #MongoDB

MongoDB Advent Calendar 2013 20日目の記事を書きました

MongoDB Advent Calendar 2013に招待いただいたので20日目の記事を書きました。