Facebooker
FacebookerはRuby on Rails用のFacebookプラグインです。
Facebookアプリケーションを作ったりFBMLのヘルパーがあったりREST APIへのラッパーが用意されていて、大変に便利が良いです。
使い方は
チュートリアル
http://apps.facebook.com/facebooker_tutorial/
や
Developing Facebook Platform Applications with Rails
http://www.pragprog.com/titles/mmfacer/developing-facebook-platform-applications-with-rails
を参考にしてください。
書籍の方はちょっと情報が古いのですが、それでも十分役立ちます。
ユーザー情報の取得方法
Facebookerでのユーザー情報の取得は、とてもRails的でわかりやすいです。
script/console で実行する場合
# Facebook ユーザーID
facebook_id = 1234567890
# Facebookのセッションキー
session_key = 'xxxxxxxxxxxxxxxxxxxxxxxxx'
# Facebook APIにアクセスするためのセッション作成
fb_session = Facebooer::Session.create
fb_sessoin.secure_with!(fb_sessoin, facebook_id, 1.hour.from_now)
fb_session.user #=> セッションユーザー情報。Facebooker::Userのインスタンス
fb_session.user.friends #=> セッションユーザーの友人のユーザー情報。Facebooker::Userインスタンスの配列
ユーザー情報の取得には、Users.getInfo APIを利用する。
ユーザー情報のキャッシュ
Facebooker::Userインスタンスは、生成された後、最初にプロパティ(#name, #age ..etc)にアクセスしたタイミングでUsers.getInfo APIにリクエストを投げる。一度リクエストしたら、2度目はキャッシュしたメモリから値を返す。
Facebooker::Userインスタンスを作成しても、プロパティにアクセスしなければUsers.getInfo APIをリクエストしないので、少しはパフォーマンスに効果があるのかもしれない。
user = fb_session.user # まだREST APIにリクエストしてない
user.name #=> 'Yukio Hatoyama' このタイミングでREST APIにリクエストしている
user.sex #=> 'Male' メモリーから取得
同じユーザーでもキャッシュは効かない場合がある、ていうかほとんど。
基本的にはインスタンス変数にデータを蓄えているだけなので、同じFacebookユーザーでもオブジェクトが違えば、キャッシュは当然効いていないため、それぞれAPIへリクエストすることになる。
# UID123456789のユーザー
user = Facebooker::User.new(123456789, fb_session)
# users.getInfo APIにアクセスする
user.name #=> 'Yukio Hatoyama'
# 同じUIDを持つユーザー
sameuser = Facebooker::User.new(123456789, fb_session)
# Users.getInfo APIにアクセスする
sameuser.name #=> 'Yukio Hatoyama'
フレンド情報の取得
Facebookerでのフレンド情報取得は、Facebooker::User#friendsを利用することになる。
このようなAPIがFacebookに存在しているわけではなくて、Friends.get APIで友人のID一覧を取得した後にその人数分Users.getInfo APIをリクエストしにいっている。
従って、かなり効率が悪いです・・。
user = Facebooker::User.new(123456789, fb_session)
user.friends #=> Userインスタンスの配列コレクション。友達が20人いれば、リクエスト数は21回。
フレンド情報のキャッシュ
フレンド情報の取得にはキャッシュが効く。効かなかったらやばいよね。
user = Facebooker::User.new(123456789, fb_session)
# フレンド数分、users.getInfo APIをリクエスト
user.friends
# メモリのキャッシュから返すので、APIはリクエストしない
user.friends
# プロパティを指定した場合、もう一度人数分リクエストする
user.friends([:name, :sex])
# キャッシュから返すのでAPIはリクエストしない
user.friends([:name, :sex])
これもUserインスタンス内の変数にキャッシュしているだけだから、あまり効果なさそうだなぁ。。
最後に
FacebookerはFacebookアプリをRubyで作りたい場合、とても便利です。
情報も他のライブラリに比べて一番充実していると思います。
僕もこれまでFacebook関連のアレをやってきましたが、Facebookerのインターフェイスの良さにはしびれっぱなしです。
キャッシュに関しては、FacebookのユーザーIDベースでKey Value Storeに保持しておけるようにできたらいいなと思っていますが、Facebookの規約的にアウトじゃないのか?とか、そもそもユーザー情報の見え方がユーザーによっては違うはずなので、やっぱりサービス全体でキャッシュするのはダメかなぁ。
追記
Facebooker::User#users(ids)メソッドを使えば、リクエストが1回で済むことがわかった。
基本的にはこっちを使おうかな。
Posted in
ruby,
ruby on rails at 2月 19th, 2010.
1 Comment.
FLASHer のためのSinatra入門 [導入編]
前回の続きです。
今回は大量のダミーデータを返すAPIを作ってみます。
要件としては
- 住所録を返すAPI
- 本番サーバはPHPなので、URLもそれに合わせる
- 100件程度、ランダムで返す
- XMLの内容は、名前、メール、メッセージ、性別、国
という感じです。
Read More...
Posted in
flash,
ruby,
sinatra,
未分類 at 2月 17th, 2010.
No Comments.
Sinatra 楽しい!
今のところあまり大きなものを作る予定がないんだけど、ひとつのファイルにたくさんのルートを書いているとごちゃごちゃしてちょっと嫌だ。
かといってコントローラーを複数に別けるのもSinatraスタイルに反しているような気がする。そこでルートの階層をわかりやすくするTIPS。
def namespace routename, &block
yield
end
namespaceというメソッドをトップレベルに定義しておく。このメソッドはブロックの内容を実行するだけ。
get '/users' do
'Users Index'
end
get '/users/new' do
'New User'
end
get '/todos' do
'Todos Index'
end
get '/todos/:id' do
"Show Todo #{params[:id]}"
end
これが
namespace '/users' do
get '/users' do
'Users Index'
end
get '/users/new' do
'New User'
end
end
namespace '/todos' do
get '/todos' do
'Todos Index'
end
get '/todos/:id' do
"Show Todo #{params[:id]}"
end
end
こう書けるようになる。
少し見やすい
Posted in
ruby,
sinatra at 2月 16th, 2010.
No Comments.
はじめに
こんにちはーFlasherのみなさん。
すっかりRuby記事ばっかりなのに、いまだにブログ訪問者の大半はFlasherらしいこのブログ。
久しぶりにFLASHerのための記事を書けそうです。
今日とりあげるのはSinatraというRubyで作られた超シンプルなフレームワークです。
require 'rubygems'
require 'sinatra'
get '/hi' do
"Hello World!"
end
このたった5行で、http://localhost:4567/hi にアクセスすると「Hello World!」というテキストを返すAPIサーバがローカルPC上に完成するんだ。
Rubyがわからなくたって、どんなプログラムなのか一目瞭然だ。シンプルだと思わないかい?
今回はこのシンプルなSinatraを使って、あなたのFlash案件に使える、より本番に近いモックAPIサーバを作ろうというお話です。
Read More...
Posted in
flash,
ruby,
sinatra,
未分類 at 2月 16th, 2010.
2 Comments.
Railsで最近人気の認証フレームワーク「Authlogic」は、ユーザーセッションをまるでActiveRecord風なモデルのように扱えることによって、セッション周りの処理をコントローラーからモデル側へ移すことができていて、コードがシンプルになります(コントローラーがごちゃごちゃしないという点で)。
AuthlogicではユーザーセッションをAuthlogic::Session::Baseを継承したクラスで管理するようになっており
# user_session.rb
class UserSession <Authlogic::Session::Base
end
# ログインする
session = UserSession.new(:login => "bjohnson", :password => "my password", :remember_me => true)
session.save
# ログインしているユーザーセッションを取得する
current_user_session = UserSession.find
# ログアウトする
session.destroy
と、こんな感じのインターフェイスでログイン周りの処理が書けて、非常にわかりやすい。
しかし隠蔽されているとはいえ、モデルからセッションやCookieにアクセスするといった事を自分で実装したことがなかったので、一体どんな仕組になっとるんか?と考え調べました。
読んだポインタ
http://github.com/binarylogic/authlogic/blob/master/lib/authlogic/controller_adapters/abstract_adapter.rb
http://github.com/binarylogic/authlogic/blob/master/lib/authlogic/controller_adapters/rails_adapter.rb
3行で説明
- ActionControllerのbefore_filterの先頭で
- ActionControllerをラップしたアダプタークラス(RailsAdapter)への参照を
- Authlogic::Session::Base.controllerに代入している
モジュールをインクルードしている箇所
http://github.com/binarylogic/authlogic/blob/master/lib/authlogic/controller_adapters/rails_adapter.rb#L48
ActionController::Base.send(:include, Authlogic::ControllerAdapters::RailsAdapter::RailsImplementation)
コントローラーの先頭のフィルターに:activate_authlogicという処理を追加している箇所
http://github.com/binarylogic/authlogic/blob/master/lib/authlogic/controller_adapters/rails_adapter.rb#L36
klass.prepend_before_filter :activate_authlogic
Authlogic::Session::Base.controllreにコントローラーのアダプターを代入している箇所
http://github.com/binarylogic/authlogic/blob/master/lib/authlogic/controller_adapters/rails_adapter.rb#L40-42
def activate_authlogic
Authlogic::Session::Base.controller = RailsAdapter.new(self)
end
とても勉強になったんだけど、Authlogicはソースが綺麗に分割されすぎてて探しにくい。
Posted in
ruby,
ruby on rails at 2月 15th, 2010.
No Comments.
前田製作所さんの作った「ナゼナゼくん」というサービスがおもしろい。
自分の問題だと思っている事柄を入力すると、「なんで××なのですか?」としつこく質問されつづけているうちに、自分と向き合わざるを得なくなるツールです。


まぁ、どんな不満も結局は自分に問題があるという結果になってしまうというか、そうでない方が問題なのだけど、いくらWebサービスとは言え、質問攻めにされるのはいい気分じゃないです。
結構むかむかして、心がささくれだってくるんですが、訳のわからんキャラのせいでどーでもよくなります。

つーか何、残像してんだよ。
Posted in
Webサービス at 2月 3rd, 2010.
No Comments.
Railsで非同期処理?
railsで非同期処理をやる場合、最近はdelayed_jobがメジャーらしいですね。
以前はbackgrounDRbが定番だったようだけど、EngineYardが「友達にBackgrounDRbを使わせるな」とまで書いているので、そこまで言われると使う気になりませんでした。実際リソース食いだったし。
使い方参考ページ
使い方はそんなに難しくないので、ここで説明することは放棄します。
READMEとRailscastsのエピソード171でなんとかなると思います。
再試行のロジック
いろいろとすっとばして本題、キューの再試行のロジックが変だなぁと思ったのでメモです。
Delayed::Job::max_attempts
delayed_jobには試行回数上限があって、この上限値を超えるまでリトライしつづけます。
デフォルトは25回で、Delayed::Job::max_attempts という定数に設定されています。
Delayed::Worker::sleep_delay
ワーカーが起動するインターバルです。デフォルトは5秒。
例えば絶対に失敗するキューがあった時、
キュー失敗、5秒待機、キュー失敗、5秒待機、(以下25回失敗するまで繰り返し)
という流れを勝手にイメージしていたのですが、そうではないみたいです。
キューが失敗した時の再スケジューリング
キューが失敗すると、次に実行する予定時刻を決めます。そのロジックが
On failure, the job is scheduled again in 5 seconds + N ** 4, where N is the number of retries.
となっています。
「トライした回数の4乗に5秒足した時間」後にリトライをするよう再スケジューリングするので、失敗すればするほどインターバルが開いていきます。
1回失敗したら次回のリトライは6秒後
2回失敗したら次回のリトライは21秒後
3回失敗したら次回のリトライは86秒後
4回失敗したら次回のリトライは261秒後
5回失敗したら次回のリトライは630秒後
6回失敗したら次回のリトライは1301秒後
7回失敗したら次回のリトライは2406秒後
8回失敗したら次回のリトライは4101秒後
9回失敗したら次回のリトライは6566秒後
10回失敗したら次回のリトライは10005秒後
最初の方は1分以内にリトライさせますが、10回目ともなるとリトライは2時間後。
何度も失敗していると、もうこいつアカンわ・・と見捨てられていく感じを良く表現したロジックですねー。
Posted in
ruby on rails,
日記 at 12月 15th, 2009.
No Comments.
久しぶりにmixiアプリの事を調査したよ。
多分日頃からOpenSocial開発をしてる人には当たり前のことなんだろうけど
ぐぐってもわからなかったので。。
iframeで外部ページを埋め込めるか?
mixiアプリはそもそもiframe内にgadget.xmlをキャッシュされた状態で起動する。
つまり、mixi.jp内のページにmixi-platform.comにキャッシュされたコンテンツを表示していて
さらにその中で別ドメインなコンテンツを表示できるのか?
結論としてはできる。
ただ外部ページからではOpenSocialAPIに接触しようがないから、不便は不便。
iframeの中にfacebookアプリを埋め込んだりもできたよ。
でもmixiアプリ上で認証させるのは多分規約違反。
iframeで外部コンテンツを表示するっていう作法も、外部サイトへの遷移の規約に従ってない気がするのでアウトかな?
どうでしょう?
Flashから外部コンテンツとの通信
OpenSocialのFlash埋め込みAPIを使って、配置したSWFから
URLLoaderなんかを使って普通にクロスドメインな通信ができるかチェック。
これもできる。相手のサーバから拒否されてなければ。
JavaScriptはXHRを使えないから(ひょっとして使える?)、makeRequestするわけだけど
Flashは普通に通信できるなら、mixiアプリは開発しやすさで言えばFlashで作るに限るってことかなぁ。
makeRequestはoAuthの署名リクエストが使えるので、通信にセキュリティを保証したい場合は有効だと思う。
なんかto_jsonについて調べてたら
activerecord/lib/active_record/serializers/json_serializer.rb
にらきすたのこなたが出てくるんだけど、これって有名なんだろうか・・。
あまりにも意外すぎて、なんの作業してたか忘れたよ。いい迷惑だ!
http://github.com/rails/rails/blob/55501b9f6ab46d45db04a81956579402511ad092/activerecord/lib/active_record/serializers/json_serializer.rb#L18-75
--
追記:
例えばこんな感じ、コメントの中にサンプルコードとして登場します
# konata = User.find(1)
# ActiveRecord::Base.include_root_in_json = true
# konata.to_json
# # => { "user": {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true} }
はてブのコメントによると2年前からコードの中に存在していたらしい。
アニメ好きな外人のコミッターが犯人だったんすね。
http://blog.codefront.net/2007/10/15/konata-izumi-in-edge-rails/
Posted in
ruby on rails at 11月 2nd, 2009.
No Comments.

RailsCasts大好きです。
- Rails好き
- わかりやすい
- ネタが早い
- 声が素敵
などいろいろ良い点がありますね。
さて、最近TextMateを使うようになりまして(メインはNetBeansです)
あこがれのRailsCastsみたいな色にしたいと奮闘しましたが
本家からダウンロードできるのでした・・
http://railscasts.com/about
好きな人はぜひ!
Posted in
ruby at 10月 30th, 2009.
No Comments.