Skip to content

Instantly share code, notes, and snippets.

@cqr
Created August 29, 2010 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cqr/556451 to your computer and use it in GitHub Desktop.
Save cqr/556451 to your computer and use it in GitHub Desktop.
# USING THIS IN SINATRA
#
# require 'sinatra'
# require 'declarative_parameters'
# helpers DeclarativeParameters
#
# get '/some/uri' do
# required :name
# required :age, :type => :int, :min => 18
#
# # I now know that @name is set and not blank, and @age is an int
# # over 18.
# end
module DeclarativeParameters
def required(*required_fields)
options = required_fields.pop if required_fields.last.kind_of? Hash; options ||= {}
raise RequiredFieldsMissing.new(*required_fields) if required_fields.any?{|f| params[f].blank? }
optional(*required_fields + [options])
end
def optional(*optional_fields)
options = optional_fields.pop if optional_fields.last.kind_of? Hash; options ||= {}
optional_fields.each do |field|
instance_variable_set("@#{field}", options[:default]) and next if params[field].nil?
params[field] = params[field].send("to_#{options[:type].to_s[0,1]}")
raise TooSmall.new(field, params[field], options[:min]) if options[:min] and params[field] < options[:min]
raise TooBig.new(field, params[field], options[:max]) if options[:max] and params[field] > options[:max]
instance_variable_set("@#{field}", params[field])
end
end
def self.included(klass)
klass.instance_eval do
error [RequiredFieldsMissing, TooSmall, TooBig] do
status 422
{:error => env['sinatra.error'].message}.to_json
end
end if klass.is_a? Sinatra::Application
end
end
class RequiredFieldsMissing < Exception
def initialize(*fields)
super fields.map(&:to_s).join(', ') + ' are required for this request.'
end
end
class TooSmall < Exception
def initialize(name, actual, minimum)
super "#{name} is too small. Minimum is #{minimum}, got '#{actual}'."
end
end
class TooBig < Exception
def initialize(name, actual, maximum)
super "#{name} is too big. Maximum is #{maximum}, got '#{actual}'."
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment