--- layout: old_post title: TwitterのAPIでRailsのActive Resouceを試してみる permalink: /tatsuya/show/318-twitter-api-rails-active-resouce ---

P1010461

昨日のスクリプトを書いていて思ったけど、TwitterのAPIってRESTだよね(完全にではないけど)、これってActiveResourceでアクセスすれば簡単だったの?と思った。ということでActiveResourceの勉強もかねて試してみた、結果としては慣れればかなり楽、「Postクラスは暗黙的にPostテーブルを見る」のように命名規則に従ってスマートにWebサービスへアクセスすることができる、SOAPのWSDLみたいな型定義を準備する必要ないのは良いよね。ActionWebServiceですら型定義が結構めんどくさいしね。
あとついでに昨日のスクリプトをWebサービスにしてみよう

まず新しいRailsアプリを作る(今回はTwittとかで)、そこに最新のEdgeなRailsを落としてくる

rails twitt
cd twitt/vendor/
sudo svn co http://dev.rubyonrails.org/svn/rails/trunk rails

これでActiveResourceを試せるはず、こんな感じらしい

   1| #Hogeリソースを定義
   2| class Hoge < ActiveResource::Base
   3|   self.site = "http://foo.com/"
   4| end
   
   #基本形
   #GET http://foo.com/hoges/1.xml
   >> Hoge.find(1)
    
   #カスタムメソッド
   #GET http://foo.com/hoges/show.xml?name=tatsuya
   >> Hoge.find(:show, :name=>"tatsuya")

あわせてTwitterのAPIを見る翻訳版ありがたい:)
で準備完了、まずはStatusを作ってみる。あとクラスが増えてきそうなのでTwitter::Status, Twitter::User みたいにTwitterモジュールを作ってみる

   #app/model/twitter.rb
   1| module Twitter
   2|   USER = "ユーザ名"
   3|   PASSWORD = "パスワード"
   4|   SITE = "http://#{Twitter::USER}:#{Twitter::PASSWORD}@twitter.com/"
   5| end

   #app/model/twitter/status.rb
   1| class Twitter::Status < ActiveResource::Base
   2|   self.site = Twitter::SITE
   3| end

   #app/model/twitter/user.rb
   1| class Twitter::User < ActiveResource::Base
   2|   self.site = Twitter::SITE
   3| end

本気で簡単、動かしてみる

#consoleにURL表示すると判りやすいので、ちょっと手を加えて #twitt/vendor/rails/activeresource/lib/active_resource/connection.rb 87| def request(method, path, *arguments) 88| p method.to_s +" "+ path.to_s #Pathを表示

追記:こんな面倒なことする必要なかった・・
I sort my thought... - ActiveResourceを少し触ってみた
loggerをクラスメソッドとして渡せば良いらしい、self.logger = Logger.new($stderr) なるへそ。

ruby script/console
   1| #自分の全発言
   2| >> Twitter::Status.get(:user_timeline)
   3| "get /statuses/user_timeline.xml"
   4| => [{"user"=>{"name"=>"okui", "url"=>nil, "id"=>"5714242", "description"=>nil, "protected"=>"false", "screen_name"=>"okui2000", 
   5| 
   6| #id指定で取得
   7| >> Twitter::Status.get(:show, :id=>48195602)
   8| "get /statuses/show.xml?id=48195602"
   9| => {"user"=>{"name"=>"okui", "url"=>nil, "id"=>"5714242", "description"=>nil, "protected"=>"false", "screen_name"=>"okui2000", 
  10| 
  11| #friends全員取得
  12| >> Twitter::Status.get(:friends)
  13| "get /statuses/friends.xml"
  14| => [{"status"=>{"text"=>"たの中あと56ページ! .", "id"=>"48258352", "created_at"=>"Thu May 03 09:15:14 +0000 2007"},  "name
  15| 
  16| #friendsid指定で
  17| >> Twitter::User.get(:show, :id=>3667401)
  18| "get /users/show.xml?id=3667401"
  19| => {"status"=>{"text"=>"vaya timo de concurso.... Pep, esto huele...", "id"=>"46432622", "created_at"=>"Tue May 01 22:33:45 +0000 2007"}, "profile_sidebar_fill_color"=>"e0ff92", "name"=>"show"....... 

/users/show の結果がおかしい?・・・・・・・・・あ、"show"というnameのユーザを取ってるのか:(

   1| #無理矢理
   2| >> Twitter::User.get("show/3667401")
   3| "get /users/show/3667401.xml"
   4| => {"status"=>{"text"=>"たの中あと56ページ! .", "id"=>"48258352", "created_at"=>"Thu May 03 09:15:14 +0000 2007"}.........

最後の /users/show/id.xml は上手くやる方法無いのかな?むむ

追記:get() で帰ってくるのはあくまでハッシュ配列だから、Statusオブジェクトのインスタンスとして得るためにはfind() を呼ぶ必要があるんだね。

>> status = t.find("show/35776212")
"get/statuses/show/35776212.xml"
=> #<Twitter::Status:0x24ce5c0 @prefix_options={}, @attributes={"user"=>#<Twitter::User:0x24cd580 @prefix_options={},.........
#Statusオブジェクトのインスタンスが返ってくる

>> status.text
=> "今日はロブスター食ってきた。旨い ."
>> status.created_at
=> "Sun Apr 22 09:03:48 +0000 2007"