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.
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.

RailsCasts大好きです。
- Rails好き
- わかりやすい
- ネタが早い
- 声が素敵
などいろいろ良い点がありますね。
さて、最近TextMateを使うようになりまして(メインはNetBeansです)
あこがれのRailsCastsみたいな色にしたいと奮闘しましたが
本家からダウンロードできるのでした・・
http://railscasts.com/about
好きな人はぜひ!
Posted in
ruby at 10月 30th, 2009.
No Comments.
個人的メモ
結構リソース食うので次はdelayed_jobにしたい・・
実行してことはあるけど、正常に終了してないキューを取得する
BdrbJobQueue.find(:all, :conditions => ['finished = ? AND taken = ?',0,1])
キューをもう一回実行させる
上の合わせ技
BdrbJobQueue.find(:all, :conditions => ['finished = ? AND taken = ?',0,1]).each do |job|
job.release_job
end
Posted in
ruby,
ruby on rails at 9月 30th, 2009.
No Comments.
Amazon CloudFrontはAmazon S3上のファイルをキャッシュするソリューションです。
前回paperclipからS3を使う設定はわかったので、今回はさらにCloudFrontを利用するための設定です
前回のおさらい
has_attached_file :avatar,
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style.:extension",
:bucket => 'mybucket'
前回こんな感じでS3の設定をしました。
コンソールから利用してみると
user = User.new
user.avatar = File.open('/tmp/myface.jpg')
user.save
puts user.avatar.url #=> http://mybucket.s3.amazonaws.com/avatar/1/original.jpg
こんな感じでS3のURLがとれるようになっているはず。
s3_host_aliasを効かす
キャッシュサービスであるCloudFrontを利用する場合は、ホスト名を適宜変えるだけなので
paperclipが勝手にやってくれるといいなぁ〜なんて思いました。
has_attached_file :avatar,
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style.:extension",
:bucket => 'mybucket',
:s3_host_alias => "xxxxxxxxxxxx.cloudfront.net",
:url => ":s3_alias_url"
オプションが2つ増えてます
- :s3_host_alias は、エイリアスのFQDNを記述しておきます。
- :url には「":s3_alias_url"」を記述します。注意なのは、rubyのシンボルじゃなくて、文字列だってところです。ハマりました。
user = User.new
user.avatar = File.open('/tmp/myface.jpg')
user.save
puts user.avatar.url #=> http://xxxxxxxxxxxx.cloudfront.net/avatar/1/original.jpg
わーーこりゃ幸せだ。
余談
さらにサイト全体でアセット関係(public以下)もCloudFrontにしたければ
config/environments/#{RAILS_ENV}.rb 内で
config.action_controller.asset_host = "http://xxxxxxxxxxxx.cloudfront.net"
こうしとけば、image_path()やらimage_tag()やらjavascript_include_tag()やらを使ったときに、リクエスト先を書き換えてくれてさらに幸せ度アップ
Posted in
ruby,
ruby on rails at 9月 10th, 2009.
No Comments.
PaperClipはとってもシンプルなActiveRecordで添付ファイルを管理するプラグインです。
http://github.com/thoughtbot/paperclip/tree/master
便利すぎて鼻血がでそうなプラグインです
使い方のおさらい
カラムを追加して
class AddAvatarColumnsToUser <ActiveRecord::Migration
def self.up
add_column :users, :avatar_file_name, :string
add_column :users, :avatar_content_type, :string
add_column :users, :avatar_file_size, :integer
add_column :users, :avatar_updated_at, :datetime
end
def self.down
remove_column :users, :avatar_file_name
remove_column :users, :avatar_content_type
remove_column :users, :avatar_file_size
remove_column :users, :avatar_updated_at
end
end
モデルクラスで定義
class User <ActiveRecord::Base
has_attached_file :avatar
end
とするだけですね。
詳細はRDocをみてください
Amazon S3を使う
PaperClipはストレージにS3を使うためのオプションがあります
has_attached_file :avatar,
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style.:extension",
:bucket => 'mybucket'
config/s3.ymlには
access_key_id: 456...
secret_access_key: 456...
こんな感じのアクセスキーとシークレットキーを置いておきます
productionでだけS3を使いたい
開発中はローカルで完結したい場合は
has_attached_file :avatar, Proc.new {
if RAILS_ENV == 'production'
{
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style.:extension",
:bucket => 'mybucket'
}
else
{}
end
}.call
こんな感じでいいかな
Posted in
ruby,
ruby on rails at 9月 9th, 2009.
No Comments.