pitがちょう便利だよ! (ついでに Net::Netrc の紹介)

http://subtech.g.hatena.ne.jp/cho45/20080102/1199257680
便利ですねえ。今までは Net::Netrc を利用してましたが、これからは pit を使わせていただこうと思います。

% gem install pit

でインストールできます。

使い方

説明は先ほどの url に書いてあります。そこから最初の部分だけ抜き出すと、

require 'rubygems'
require 'pit'

config = Pit.get("twitter", :require => {
	"username" => "you email in twitter",
	"password" => "your password in twitter"
})

などと書くと、設定名が twitter の設定を読み込みます。設定がない場合には、$EDITOR を利用して設定ファイルを作成します。$EDITOR が設定されていないと、エラーが出て動かないので注意が必要です。

pit に類似したものとしては、Net::Netrc というのがありますが、pit の方が多機能です。Net::Netrc は設定をファイルから読み込むだけです。ついでなので、こちらも使い方を書いておこうと思います。

Net::Netrc

インストール
% gem install net-netrc
使い方

~/.netrc に

machine "twitter"
login email@address
password your_password

などとあらかじめ書いておく必要があります。ruby からは

require 'rubygems'
require 'net/netrc'

netrc = Net::Netrc.locate "twitter"
username, password = netrc.login, netrc.password

という感じで利用します。~/.netrc は 600 あたりにしておかないと例外が発生します。

restful_authentication を題材にして routes, resource and resources のお勉強

(追記: この記事よりも、ActiveResourceとかそのルーティングとかのドキュメント - moroの日記 を読んだ方が良いと思います!)
(追記その2: restful_authentication の controller_name がバグってたのが直ったようですね。デフォルトも sessions になってます。ですので、以下の記事の session_controller まわりの記事は現在では不必要になってます)

大幅に書き換えました。hatena.vim rocks.

インストール

% cd your_rails_project
% ./script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/

controller の作成

% ./script/generate authenticated model_name [controller_name]

controller_name は省略可能(デフォルトは session)です。今回は model_name を user、controller_name を session にします。

% ./script/generate authenticated user

これで users_controller と session_controller が作られます。モデルなどもできますが、今回は触れません。

RESTful なコントローラにする

まずは users_controller と session_controller を RESTful なコントローラにします。config/route.rb を編集します。

ActionController::Routing::Routes.draw do |map|
  map.resources :users
  map.resource :session
end

map.resource と map.resources の違いについては、http://api.rubyonrails.org/classes/ActionController/Resources.html を参照すると良いと思います。session_controller には :id が必要ない(ログインとログアウトだけに使う)ので、singleton resource を選択しました。この時点で

% rake routes

を行うと、現時点での routes 設定を見ることができます。

users GET /users {:controller=>"users", :action=>"index"}
formatted_users GET /users.:format {:controller=>"users", :action=>"index"}
POST /users {:controller=>"users", :action=>"create"}
POST /users.:format {:controller=>"users", :action=>"create"}
new_user GET /users/new {:controller=>"users", :action=>"new"}
formatted_new_user GET /users/new.:format {:controller=>"users", :action=>"new"}
edit_user GET /users/:id/edit {:controller=>"users", :action=>"edit"}
formatted_edit_user GET /users/:id/edit.:format {:controller=>"users", :action=>"edit"}
user GET /users/:id {:controller=>"users", :action=>"show"}
formatted_user GET /users/:id.:format {:controller=>"users", :action=>"show"}
PUT /users/:id {:controller=>"users", :action=>"update"}
PUT /users/:id.:format {:controller=>"users", :action=>"update"}
DELETE /users/:id {:controller=>"users", :action=>"destroy"}
DELETE /users/:id.:format {:controller=>"users", :action=>"destroy"}
POST /session {:controller=>"sessions", :action=>"create"}
POST /session.:format {:controller=>"sessions", :action=>"create"}
new_session GET /session/new {:controller=>"sessions", :action=>"new"}
formatted_new_session GET /session/new.:format {:controller=>"sessions", :action=>"new"}
edit_session GET /session/edit {:controller=>"sessions", :action=>"edit"}
formatted_edit_session GET /session/edit.:format {:controller=>"sessions", :action=>"edit"}
session GET /session {:controller=>"sessions", :action=>"show"}
formatted_session GET /session.:format {:controller=>"sessions", :action=>"show"}
PUT /session {:controller=>"sessions", :action=>"update"}
PUT /session.:format {:controller=>"sessions", :action=>"update"}
DELETE /session {:controller=>"sessions", :action=>"destroy"}
DELETE /session.:format {:controller=>"sessions", :action=>"destroy"}

session_controller の方の :controller 設定が "sessions" になっているのでこれを修正します。"sessions" になっている理由は rails 2.0 で導入された new convention のためだと思います。

We’ve also instigated a new convention that all resource-based controllers will be plural by default

Rails 2.0: It’s done! | Riding Rails

session_controller を見るように変更する

config/routes.rb に書いた先ほどの設定を変更します。

ActionController::Routing::Routes.draw do |map|
  map.resources :users
  map.resource :session, :controller => "session"
end

もう一度 routes 設定を確認します(session部分のみ掲載)。

POST /session {:controller=>"session", :action=>"create"}
POST /session.:format {:controller=>"session", :action=>"create"}
new_session GET /session/new {:controller=>"session", :action=>"new"}
formatted_new_session GET /session/new.:format {:controller=>"session", :action=>"new"}
edit_session GET /session/edit {:controller=>"session", :action=>"edit"}
formatted_edit_session GET /session/edit.:format {:controller=>"session", :action=>"edit"}
session GET /session {:controller=>"session", :action=>"show"}
formatted_session GET /session.:format {:controller=>"session", :action=>"show"}
PUT /session {:controller=>"session", :action=>"update"}
PUT /session.:format {:controller=>"session", :action=>"update"}
DELETE /session {:controller=>"session", :action=>"destroy"}
DELETE /session.:format {:controller=>"session", :action=>"destroy"}

これで、:controller が "session" を見るようになりました。

ログイン、ログアウト、サインアップ用の url を用意する

動作としてはこれで良いのですが、

http://example.jp/login でログイン
http://example.jp/logout でログアウト
http://example.jp/signup でサインアップ

にしたいと思いましたので、config/routes.rb をもう少し変更します。
Routing の基本は http://api.rubyonrails.org/classes/ActionController/Routing.html で知ることができるので、それを見るとだいたいわかると思います。

ActionController::Routing::Routes.draw do |map|
  map.connect "login", :controller => "session", :action => "new"
  map.connect "logout", :controller => "session", :action => "destroy"
  map.connect "signup", :controller => "users", :action => "new"
  map.resources :users
  map.resource :session, :controller => "session"
end

ビューで楽をするために Named routes を利用する

あとは、ビューで link_to などで /login などに飛びたいときにいちいち :controller などを書くのがめんどいので、login_path とか logout_path とかで表現できるようにすると楽です。そのために、map.connect ではなく、map._name_of_root_ を使います。

ActionController::Routing::Routes.draw do |map|
  map.login "login", :controller => "session", :action => "new"
  map.logout "logout", :controller => "session", :action => "destroy"
  map.signup "signup", :controller => "users", :action => "new"
  map.resources :users
  map.resource :session, :controller => "session"
end

たとえば先頭の

  map.login "login", :controller => "session", :action => "new"

を例にとると、こう設定することで、login_url, login_path を利用できるようになります。詳しくは http://api.rubyonrails.org/classes/ActionController/Routing.html の Named routes の項を読むと良いと思います。

Don't Repeat Yourself

:controller => "session" と何度も書くのが嫌なので、まとめてしまいます。with_options を利用します。

ActionController::Routing::Routes.draw do |map|
  map.with_options :controller => "session" do |page|
    page.login "login", :action => "new"
    page.logout "logout", :action => "destroy"
    page.resource :session
  end
  map.signup "signup", :controller => "users", :action => "new"
  map.resources :users
end

session_controller と users_controller の routes 設定の順番が変わってしまいましたが、rake routes で確認したところかぶってるところもないので問題なさそうです。一応結果を表示しておきます。

login /login {:controller=>"session", :action=>"new"}
logout /logout {:controller=>"session", :action=>"destroy"}
POST /session {:controller=>"session", :action=>"create"}
POST /session.:format {:controller=>"session", :action=>"create"}
new_session GET /session/new {:controller=>"session", :action=>"new"}
formatted_new_session GET /session/new.:format {:controller=>"session", :action=>"new"}
edit_session GET /session/edit {:controller=>"session", :action=>"edit"}
formatted_edit_session GET /session/edit.:format {:controller=>"session", :action=>"edit"}
session GET /session {:controller=>"session", :action=>"show"}
formatted_session GET /session.:format {:controller=>"session", :action=>"show"}
PUT /session {:controller=>"session", :action=>"update"}
PUT /session.:format {:controller=>"session", :action=>"update"}
DELETE /session {:controller=>"session", :action=>"destroy"}
DELETE /session.:format {:controller=>"session", :action=>"destroy"}
signup /signup {:controller=>"users", :action=>"new"}
users GET /users {:controller=>"users", :action=>"index"}
formatted_users GET /users.:format {:controller=>"users", :action=>"index"}
POST /users {:controller=>"users", :action=>"create"}
POST /users.:format {:controller=>"users", :action=>"create"}
new_user GET /users/new {:controller=>"users", :action=>"new"}
formatted_new_user GET /users/new.:format {:controller=>"users", :action=>"new"}
edit_user GET /users/:id/edit {:controller=>"users", :action=>"edit"}
formatted_edit_user GET /users/:id/edit.:format {:controller=>"users", :action=>"edit"}
user GET /users/:id {:controller=>"users", :action=>"show"}
formatted_user GET /users/:id.:format {:controller=>"users", :action=>"show"}
PUT /users/:id {:controller=>"users", :action=>"update"}
PUT /users/:id.:format {:controller=>"users", :action=>"update"}
DELETE /users/:id {:controller=>"users", :action=>"destroy"}
DELETE /users/:id.:format {:controller=>"users", :action=>"destroy"}

旧バージョン(1.2.6)のrailsでプロジェクトを作る

たとえば、

% gem list rails

*** LOCAL GEMS ***
rails (2.0.2, 1.2.6)

このような状況だと、普通にプロジェクトを作ると rails 2.0.2 で作成される。あえて 1.2.6 でプロジェクトを作りたい場合、

% rails _1.2.6_ project

でいいのかな?

JavaFesta in 札幌 2007行って来た

JRubyの話があるようだったので行ってきた。「Rubyのコミュニティは札幌にはないので、おまえらもっとがんばれ(そしてコミュニティを作れ)」と言われた。
もっと知られるようにがんばります。

Ruby札幌はじめました

すでにだらさん([id:darashi:20071018:1192720675])とかsnoozer05さんとかが書かれていますが、Ruby札幌の活動の一環として、サイトを立ち上げました。
http://ruby-sapporo.org/
活動報告とか予定とかを挙げていきますので、興味のあるかたは見てくださいー。活動予定で一番近いものだと、Ruby札幌 第1回 開発集会ですね。