Posted in
ruby,
ruby on rails at 8月 16th, 2010.
No Comments.
みんな大好きRuby on Railsも、RCが出て、いよいよバージョン3登場間際といった感じですね 2010年8月30日にリリースされました。
ベータ版をいれるのはちょっと・・と尻込みしていた人(僕)も、やっと重い尻を上げてみようじゃないかと思わなくもないのではないでしょうか?
そこで、Rails3のリリース前にチェックすべき事などをメモします。
RVMをインストールして、Rails2とRails3の環境を共存させる
Rails3から、railsコマンドの挙動が大きく変わっているので、これまでのRails2も使う必要がある場合は、RVMで複数のRuby環境を準備しておくのが良いです。
Ruby Freaks Lounge 第39回 RVM(Ruby Version Manager)による環境構築
http://gihyo.jp/dev/serial/01/ruby/0039
Ruby Freaks Lounge 第40回 RVM(Ruby Version Manager)による環境構築(2)
http://gihyo.jp/dev/serial/01/ruby/0040
※追記を参照のこと
Rails2 と Rails3 の違いを、ざっくりっと学ぶ
いままで慣れ親しんだRails2のインターフェイスは、結構互換性があるので、移行に関してものすごく大きなインパクトがあるわけではないようです。
Rails2との違いを比較しながら、Rails3の新しい部分を紹介した素晴らしいスクリーンキャストがあります。
各コンポーネントごとに動画が用意されていて、資料のPDF(全86ページ)もとてもわかりやすく、一度Rails2を学んだ人であれば、ひととおり流せばRails3の新機能を把握できると思います。
Dive into Rails3
http://rubyonrails.org/screencasts/rails3
上記のプレゼン資料(PDF)
http://assets.en.oreilly.com/1/event/40/The%20Rails%203%20Ropes%20Course%20Presentation.pdf
時間がないひとはPDFを見るだけで十分ですよ。
Rails2のプロジェクトをRails3にアップデートする
既存のRails2プロジェクトをRails3にアップデートする方法は、RailsCastsで紹介されています。
Upgrading to Rails 3 Part 1
http://railscasts.com/episodes/225-upgrading-to-rails-3-part-1
Upgrading to Rails 3 Part 2
http://railscasts.com/episodes/226-upgrading-to-rails-3-part-2
Enjoy Rails3!
追記:2010-08-30
RVMはGemによるインストールが非推奨なので、こちらの方法に従うのがよいとのことです(by @babie)。
http://rvm.beginrescueend.com/rvm/install/
Posted in
ruby,
ruby on rails at 8月 10th, 2010.
No Comments.
PaperClipでクロッピングしたい場合の書き方メモ
has_attached_file :picture, :styles => { :thumb => "200x200#" }
サイズ指定の後ろに「#」で切り抜きになるようだ
Posted in
ruby,
ruby on rails at 8月 6th, 2010.
No Comments.
Rails使いの味方Herokuネタです。
HerokuでRailsアプリをデプロイする場合、タイムゾーン設定にちょっと癖があります。
Read More…
Posted in
ruby,
ruby on rails at 7月 28th, 2010.
No Comments.
ツイッターに匿名で投稿できるサービスを作りました。

つぶやき@名無しさん
http://nanasi3.com/
Read More…
NiftyGeneratorとは?
すごくニッチな話題になってしまいますが
Railsでサクっとモックを作る時、僕はnifty_generatorを使います
http://github.com/ryanb/nifty-generators
nifty_generatorはRailsCastsのryanb作の、サクっと便利でシンプルなコードを生成してくれるパッケージで
- レイアウト
- Scaffold
- 設定ファイル
- 認証処理
を生成するコマンドを提供してくれます。
RailsCasts内のサンプルアプリケーションは、いつもnifty_generatorを使ってますね。
標準のGeneratorスクリプトに比べて良い点は
- デザインがシンプルだけど適度に良く、拡張する土台にしやすい
- レイアウトが良くできている
- レイアウトだけ生成できる
という具合です。
特にScaffoldしなくてもレイアウトを生成してくれるのは、非常に便利なので僕は常用しているのですが、
最近ViewをHamlで書くようになってから、ちょっと不便だなぁと感じていました。
Haml対応してた
ヘルプみたら、普通に対応してるし・・。
script/generate nifty_layout --haml
create app/views/layouts
create public/stylesheets
exists app/helpers
create public/stylesheets/sass
create app/views/layouts/application.html.haml
create public/stylesheets/sass/application.sass
create app/helpers/layout_helper.rb
すごい!かわいい!nifty_layout!
そして僕はどんどんコードをエディタで書かなくなるんだ!
Posted in
ruby on rails at 6月 29th, 2010.
No Comments.
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.
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.
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.
なんか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.