Verb-Agnostic Matching in Sinatra

Verb-agnostic matching in Sinatra

This is possible via the multi-route extension that is part of sinatra-contrib:

require 'sinatra'
require "sinatra/multi_route"
route :get, :post, '/foo' do
# "GET" or "POST"
p request.env["REQUEST_METHOD"]
end

# Or for module-style applications
class MyApp < Sinatra::Base
register Sinatra::MultiRoute
route :get, :post, '/foo' do
# ...
end
end

However, note that you can do this simply yourself without the extension via:

foo = lambda do
# Your route here
end
get '/foo', &foo
post '/foo', &foo

Or more elegantly as a meta-method:

def self.get_or_post(url,&block)
get(url,&block)
post(url,&block)
end

get_or_post '/foo' do
# ...
end

You might also be interested in this discussion on the feature.

How can I get Sinatra to return a record matching today's date?

Something like

get '/' do
Note.first(:publish_date => Date.today)
erb :today
end

perhaps?

Handling 405's in Sinatra

Looks like it's not possible without repeating yourself a lot. From looking through the Sinatra source code, the hash of routes has the verb as the key: https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1513

It then looks up a route using that verb:
https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L943

Which is not ideal and I would consider a weakness/bug in the framework as throwing a 405 when a verb isn't allowed is standard HTTP Spec.

I'll maybe raise an issue see what the contributors say. Ideally it would store routes by their url first, and then check the appropriate verb can be executed for a given url. This would make handling something as standard as a 405, much easier.

In fact I found an issue raised on github for the above:
https://github.com/sinatra/sinatra/issues/24
As mentioned nearer the bottom, it's not currently handled and something they may work on for v2.0

Sinatra Conditions

The overall behavior of this will cause the first route to be loaded about 10% of the time and the 2nd route will be loaded the rest of the time.

The first route uses a condition set via probability. probability set above will pass its value and test to see if a random # between 0-1 is less than this probability value. Since the value is 0.1, it will return true 10% of the time.

The other 90% of the time the 2nd route will be called. The earlier routes take preference, the first valid route found will be called.

If you wanted to set the probability in another setting, you would need to defer the evaluation of the probability with a Proc.

Read more on conditional routes here:
http://www.sinatrarb.com/intro#Conditions

Sorting tweets by re-tweets/favourites

.rb file:

require 'sinatra'
require 'twitter'
require 'erb'
include ERB::Util

config = {
:consumer_key => '..' ,
:consumer_secret => '..' ,
:access_token => '..' ,
:access_token_secret => '..'
}

client = Twitter::REST::Client.new(config)
get '/list_of_tweets' do
puts "Visiting history page..."
tweets = client.user_timeline(user)
@history = tweets.take(20)
unless @params[:operation].nil?
puts "selected #{@params[:operation]}"
if @params[:operation] == "favorite_count"
@history.sort_by!{|tweet| tweet.favorite_count}
@history.reverse!
elsif @params[:operation] == "retweet_count"
@history.sort_by!{|tweet| tweet.retweet_count}
@history.reverse!
elsif @params[:operation] == "default"
puts "default"
end
end
erb :tweets_list
end

.erb file:

<!DOCTYPE html>
<html>
<head>
<title>Twitter Interface</title>
</head>
<body>

<h1>List of Tweets</h1>

<form method="post">
<h3>Sort Tweets by</h3>
<input type="radio" name="operation" value="favorite_count" checked/>Favourites
<input type="radio" name="operation" value="retweet_count"/>Retweets
<input type="radio" name="operation" value="default"/>Default
<input type="submit" value="submit"/>
</form>

<table border="1">
<tr>
<th>Time Posted</th>
<th>Description of Tweets</th>
<th>Number of Retweets</th>
<th>Number of Favourites</th>
</tr>

<% @history.each do |tweet| %>
<tr>
<td><%= tweet.created_at %></td>
<td><%= tweet.text %></td>
<td><%= tweet.retweet_count %></td>
<td><%= tweet.favorite_count %> </td>
</tr>
<% end %>
</table>
<% end %>


Related Topics



Leave a reply



Submit