ゆうなんとかさんの雑記帳的な。

Twitterで踊ったり音ゲーしたりしてるあの名前がよくわからない人が書いてるらしいよ。

これイマイチDRYじゃないなーと思ったら

DRYとは

アルファベットをひと文字ずつ、または英単語のdryと同じ読み方をしますが、「乾かせ」ではなく、「Don't Repeat Yourself」の頭文字です。早い話が「重複を避けよ」ということで、データやプログラムに重複箇所があると、そこに修正をかけたいとき大変だからなるべくかぶりがないようにしたいよねってことです。まああんまりこだわらないほうがいい事例もあるらしいですが、今回は触れないでおきます。

で、何がそうだったのか

Railsのルーティングです。ある情報をHTMLで返したいときとJSONで返したくなりましてね。何も考えずにやると中身が全く同じな2つのメソッドが出来上がるわけですよ*1…これ明らかにDRYじゃないですし、些細なことですがバグの温床です。今はJSONとHTMLだけだからいいものの、ここにXMLとかJSONPとか入ってくると…いやかんがえないでおこう
絶対なにかうまいやり方があるはずだからそんなことはせず調べてみるとやっぱり見つかりました。ちなみにこの手の仕組み、Railsに限らずたいていのWebアプリケーションフレームワーク*2にもあるはずですよ。

そこでこれを使うといい感じです

ActionController::Base#respond_toなるメソッドがあります。これでHTMLやJSONなどの切り替えができるという寸法です。詳しい仕組みは興味がありますが、同じように興味を持たれた方が調べています。たとえば、

class UsersController < ActionController::Base
  #もろもろ省略
  def show(id)
    @user = User.find id
    respond_to {|format|
      format.html # /user/1 とかでいつもどおりのレスポンスが返る
      format.json # /user/1.json とかでJSONが返る
    }
  end
end

と書いておくとHTMLとJSONを返してくれるようになります。
わりと重要なことですが、コメントにもある通りHTMLで返すとき以外は.jsonや.xmlなど、ほしいフォーマットの拡張子をURLの末尾にもつける必要があります上のリファレンスに書いてないために見落としていたおかげで、10分くらいJSONがほしいのにHTMLが返ってきて詰んでいました

*1:aliasを使う手もあるっちゃああると思うけど試してない

*2:少なくともCakePHPにはあった