Hatena::Grouphackathon

zrail (a.k.a. tobira17, h14i, ...) の Learning Log

2014-09-16

[][]Custom conditions 18:38 Custom conditions - zrail (a.k.a. tobira17, h14i, ...) の Learning Log を含むブックマーク はてなブックマーク - Custom conditions - zrail (a.k.a. tobira17, h14i, ...) の Learning Log

最近 Sinatra ばっかり触ってる。


ところで、GETのときは不要だけど、POSTのときは必要、みたいな before filter が必要になった。まぁよくある、ログイン状態によって分岐する、みたいな処理なんだけど。

class App < Sinatra::Base
  set :method do |name|
    # 引数の case を気にしたくないので downcase 付けて大文字でも小文字でも動くようにしてる
    condition { request.request_method.downcase == name.downcase }
  end

  before '/article', method: 'post' do
    redirect to('/login') unless authenticate?
  end

  get '/article' do
    # do something
  end

  post '/article' do
    # do something
  end
end

いやこの例酷いな…。こんなリソース設計有り得ないだろ…。

まぁ、サンプルの酷さはとりあえず置いておいてくだしあ。

単に GET '/article' が飛んできた場合はログインしてるかどうか関係なく同じページを返したい。しかし、 POST '/article' の場合はログイン必須、みたいな状況だと思ってください。

before '/article' だと GET と POST の両方に適用されてしまうので、フィルタの中で request_method を調べて分岐する必要がある。けど、それだとあまりにダサ読みづらいので、フィルタに入る前にそこは調べてしまいたいなぁと思って作ってみた。

モアベターな方法があるのかも知れないが、取りあえず動いてる。

ちなみにこの :method condition さん、 get とか post の condition としても指定できるけど無意味です。