• 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

これまでの流れ

  1. Method#to_source を作るには Ruby を改造するしかない
  2. それは敷居が高すぎる
  3. MIME定義部分は block で妥協しよう

ruby>>
def show
@user = User.find(params[:id])
end

show.xml {
  render :text => @user.to_xml
}

<<ruby

def と block の併用は、respond_to と同程度にキモイと気付いた

結論

そうだ!アクション定義も block にしよう!

ruby>>
show {
@user = User.find(params[:id])
}

show.xml {
  render :text => @user.to_xml
}

<<ruby

SexyActions plugin

http://github.com/maiha/sexy_actions

動作要件

  • Rails2.x

Rails2.x の scaffold が生成する不細工なコード

ruby>>
class UsersController < ApplicationController
def index
@users = User.find(:all)

respond_to do |format|
  format.html # index.html.erb
  format.xml  { render :xml => @users }
end

end

def show
@user = User.find(params[:id])

respond_to do |format|
  format.html # show.html.erb
  format.xml  { render :xml => @user }
end

end

...
<<ruby

俺達のセクシーなコード

ruby>>
class UsersController < ApplicationController
include SexyActions

index { @users = User.find(:all) }
index.html # index.html.erb
index.xml { render :xml => @users }

show { @user = User.find(params[:id]) }
show.html # show.html.erb
show.xml { render :xml => @user }

...
<<ruby

動作

  • 各アクションの定義は method_missing 経由で得られるproxyオブジェクトが行う
  • 表記の制約により、定義時のコンテキストはコントローラクラスになる
  • 従ってinstanceだけでなくclassに対してもアクション名と同名のメソッドが定義される

まとめ

  • 可読性が上がった (定義内容が1行の場合の美しさは半端ない)
  • 再利用性が上がった (あるMIMEの動作だけ再定義することができる)

致命的な問題

  • new アクションが定義できない事に気付いた><
posted by maiha maiha on Tue 29 Jul 2008 at 17:45 with 1 comment