Rails3で簡単なサンプルを作ってみた スレッド式掲示板です。

レスは追加できるけど、スレッド追加する機能は作り忘れた。

Mongoid版

http://github.com/func09/rails3_sample_bbs/tree/mongoid-20100813

ActiveRecord版

http://github.com/func09/rails3_sample_bbs/tree/activerecord-20100813

それぞれのREADMEに従えば動くはず。 rake db:seed でサンプルデータがインサートされるます。

Rails3だからといって、別段特殊なコードは書けなかった。 よくもわるくもいつもどおり書けた。

http://github.com/func09/rails3_sample_bbs/zipball/mongoid-20100813

http://github.com/func09/rails3_sample_bbs/zipball/activerecord-20100813

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 で実行する場合

  1. # Facebook ユーザーID
  2. facebook_id = 1234567890
  3.  
  4. # Facebookのセッションキー
  5. session_key = 'xxxxxxxxxxxxxxxxxxxxxxxxx'
  6.  
  7. # Facebook APIにアクセスするためのセッション作成
  8. fb_session = Facebooer::Session.create
  9. fb_sessoin.secure_with!(fb_sessoin, facebook_id, 1.hour.from_now)
  10.  
  11. fb_session.user #=> セッションユーザー情報。Facebooker::Userのインスタンス
  12. fb_session.user.friends #=> セッションユーザーの友人のユーザー情報。Facebooker::Userインスタンスの配列


ユーザー情報の取得には、Users.getInfo APIを利用する。

ユーザー情報のキャッシュ

Facebooker::Userインスタンスは、生成された後、最初にプロパティ(#name, #age ..etc)にアクセスしたタイミングでUsers.getInfo APIにリクエストを投げる。一度リクエストしたら、2度目はキャッシュしたメモリから値を返す。

Facebooker::Userインスタンスを作成しても、プロパティにアクセスしなければUsers.getInfo APIをリクエストしないので、少しはパフォーマンスに効果があるのかもしれない。

  1. user = fb_session.user # まだREST APIにリクエストしてない
  2. user.name #=> 'Yukio Hatoyama' このタイミングでREST APIにリクエストしている
  3. user.sex #=> 'Male' メモリーから取得


同じユーザーでもキャッシュは効かない場合がある、ていうかほとんど。

基本的にはインスタンス変数にデータを蓄えているだけなので、同じFacebookユーザーでもオブジェクトが違えば、キャッシュは当然効いていないため、それぞれAPIへリクエストすることになる。

  1. # UID123456789のユーザー
  2. user = Facebooker::User.new(123456789, fb_session)
  3. # users.getInfo APIにアクセスする
  4. user.name #=> 'Yukio Hatoyama'
  5.  
  6. # 同じUIDを持つユーザー
  7. sameuser = Facebooker::User.new(123456789, fb_session)
  8. # Users.getInfo APIにアクセスする
  9. sameuser.name #=> 'Yukio Hatoyama'


フレンド情報の取得

Facebookerでのフレンド情報取得は、Facebooker::User#friendsを利用することになる。 このようなAPIがFacebookに存在しているわけではなくて、Friends.get APIで友人のID一覧を取得した後にその人数分Users.getInfo APIをリクエストしにいっている。

従って、かなり効率が悪いです・・。

  1. user = Facebooker::User.new(123456789, fb_session)
  2. user.friends #=> Userインスタンスの配列コレクション。友達が20人いれば、リクエスト数は21回。


フレンド情報のキャッシュ

フレンド情報の取得にはキャッシュが効く。効かなかったらやばいよね。

  1. user = Facebooker::User.new(123456789, fb_session)
  2.  
  3. # フレンド数分、users.getInfo APIをリクエスト
  4. user.friends
  5.  
  6. # メモリのキャッシュから返すので、APIはリクエストしない
  7. user.friends
  8.  
  9. # プロパティを指定した場合、もう一度人数分リクエストする
  10. user.friends([:name, :sex])
  11.  
  12. # キャッシュから返すのでAPIはリクエストしない
  13. 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を継承したクラスで管理するようになっており

  1. # user_session.rb
  2. class UserSession <Authlogic::Session::Base
  3. end
  4.  
  5. # ログインする
  6. session = UserSession.new(:login => "bjohnson", :password => "my password", :remember_me => true)
  7. session.save
  8.  
  9. # ログインしているユーザーセッションを取得する
  10. current_user_session = UserSession.find
  11.  
  12. # ログアウトする
  13. 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行で説明

  1. ActionControllerのbefore_filterの先頭で
  2. ActionControllerをラップしたアダプタークラス(RailsAdapter)への参照を
  3. Authlogic::Session::Base.controllerに代入している

モジュールをインクルードしている箇所 http://github.com/binarylogic/authlogic/blob/master/lib/authlogic/controller_adapters/rails_adapter.rb#L48

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

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

  1. def activate_authlogic
  2.   Authlogic::Session::Base.controller = RailsAdapter.new(self)
  3. end


とても勉強になったんだけど、Authlogicはソースが綺麗に分割されすぎてて探しにくい。

Posted in ruby, ruby on rails at 2月 15th, 2010. No Comments.

friendship.rb — bdd_sample

RailsCasts大好きです。

  • Rails好き
  • わかりやすい
  • ネタが早い
  • 声が素敵

などいろいろ良い点がありますね。

さて、最近TextMateを使うようになりまして(メインはNetBeansです) あこがれのRailsCastsみたいな色にしたいと奮闘しましたが 本家からダウンロードできるのでした・・

http://railscasts.com/about

好きな人はぜひ!

Posted in ruby at 10月 30th, 2009. No Comments.

個人的メモ

結構リソース食うので次はdelayed_jobにしたい・・

実行してことはあるけど、正常に終了してないキューを取得する

  1. BdrbJobQueue.find(:all, :conditions => ['finished = ? AND taken = ?',0,1])


キューをもう一回実行させる

  1. BdrbJobQueue#release_job


上の合わせ技

  1. BdrbJobQueue.find(:all, :conditions => ['finished = ? AND taken = ?',0,1]).each do |job|
  2.   job.release_job
  3. end


Posted in ruby, ruby on rails at 9月 30th, 2009. No Comments.

Amazon CloudFrontはAmazon S3上のファイルをキャッシュするソリューションです。

前回paperclipからS3を使う設定はわかったので、今回はさらにCloudFrontを利用するための設定です

前回のおさらい

  1. has_attached_file :avatar,
  2.   :storage => :s3,
  3.   :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
  4.   :path => ":attachment/:id/:style.:extension",
  5.   :bucket => 'mybucket'


前回こんな感じでS3の設定をしました。

コンソールから利用してみると

  1. user = User.new
  2. user.avatar = File.open('/tmp/myface.jpg')
  3. user.save
  4.  
  5. puts user.avatar.url #=> http://mybucket.s3.amazonaws.com/avatar/1/original.jpg


こんな感じでS3のURLがとれるようになっているはず。

s3_host_aliasを効かす

キャッシュサービスであるCloudFrontを利用する場合は、ホスト名を適宜変えるだけなので paperclipが勝手にやってくれるといいなぁ〜なんて思いました。

  1. has_attached_file :avatar,
  2.   :storage => :s3,
  3.   :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
  4.   :path => ":attachment/:id/:style.:extension",
  5.   :bucket => 'mybucket',
  6.   :s3_host_alias => "xxxxxxxxxxxx.cloudfront.net",
  7.   :url => ":s3_alias_url"


オプションが2つ増えてます

  • :s3_host_alias は、エイリアスのFQDNを記述しておきます。
  • :url には「":s3_alias_url"」を記述します。注意なのは、rubyのシンボルじゃなくて、文字列だってところです。ハマりました。
  1. user = User.new
  2. user.avatar = File.open('/tmp/myface.jpg')
  3. user.save
  4.  
  5. puts user.avatar.url #=> http://xxxxxxxxxxxx.cloudfront.net/avatar/1/original.jpg


わーーこりゃ幸せだ。

余談

さらにサイト全体でアセット関係(public以下)もCloudFrontにしたければ

config/environments/#{RAILS_ENV}.rb 内で

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

便利すぎて鼻血がでそうなプラグインです

使い方のおさらい

カラムを追加して

  1. class AddAvatarColumnsToUser <ActiveRecord::Migration
  2.     def self.up
  3.       add_column :users, :avatar_file_name,    :string
  4.       add_column :users, :avatar_content_type, :string
  5.       add_column :users, :avatar_file_size,    :integer
  6.       add_column :users, :avatar_updated_at,   :datetime
  7.     end
  8.  
  9.     def self.down
  10.       remove_column :users, :avatar_file_name
  11.       remove_column :users, :avatar_content_type
  12.       remove_column :users, :avatar_file_size
  13.       remove_column :users, :avatar_updated_at
  14.     end
  15.   end


モデルクラスで定義

  1. class User <ActiveRecord::Base
  2.     has_attached_file :avatar
  3. end


とするだけですね。 詳細はRDocをみてください

Amazon S3を使う

PaperClipはストレージにS3を使うためのオプションがあります

  1. has_attached_file :avatar,
  2.     :storage => :s3,
  3.     :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
  4.     :path => ":attachment/:id/:style.:extension",
  5.     :bucket => 'mybucket'


config/s3.ymlには

  1. access_key_id: 456...
  2. secret_access_key: 456...


こんな感じのアクセスキーとシークレットキーを置いておきます

productionでだけS3を使いたい

開発中はローカルで完結したい場合は

  1. has_attached_file :avatar, Proc.new {
  2.     if RAILS_ENV == 'production'
  3.       {
  4.         :storage => :s3,
  5.         :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
  6.         :path => ":attachment/:id/:style.:extension",
  7.         :bucket => 'mybucket'
  8.       }
  9.     else
  10.       {}
  11.     end
  12.   }.call


こんな感じでいいかな

Posted in ruby, ruby on rails at 9月 9th, 2009. No Comments.