With Sinatra before and after filters are easy. Adding conditions to these filters is also easy but what if I want to only execute a filter if the request type is POST for example? Of course, what I want to do didn’t exist so here I show you how to create your own filter conditions.

Existing pre/post filters in Sinatra are pretty easy:

before do
  puts "Always do this before routes"
end

before '/hello' do
  puts "Always do this before /hello"
end

after '/abc/xyz' do
  puts "You visited /abc/xyz"
end

You can also use existing conditions just like routes on these filters:

before :agent => /LaLaBrowser/ do
  puts "Special stuff for this crazy browser."
end

But, as usual, a condition didn’t exist (that I could find!) to accomplish my task… execute a filter based on the HTTP request method. Thus, I came up with this simple solution creating my own condition method:

module Sinatra
  class Base
    private

    def self.request_method(*meth)
      condition do
        this_method = request.request_method.downcase.to_sym
        if meth.respond_to?(:include?) then
          meth.include?(this_method)
        else
          meth == this_method
        end
      end
    end
  end
end

This allows me to perform filters only for post, put or delete operations for example:

before :request_method => :post do
  stop 404 unless csrf_valid?
end

Or a list of possible method types:

before :request_method => [ :post, :put, :delete ] do
  puts "blah blah blah"
end

I was really surprised not to find this in Sinatra, so if I’ve missed it please let me know!