How to use params with slashes with Sinatra? - ruby

Playing with sinatra, I'm stuck on a little problem : when I use params with slashes, it confuses the router engine. So is there a nice way to handle this kind of param without having to encode it ?
The code looks like
get 'add/:url' do
#....
end
And I intend to get something like /add/http://sctackoverflow.com/ working

Did you try to use splat parameters?
Something like:
get '/add/*' do
protocol = params[:splat].first
address = params[:splat][1..-1].join('/')
url = protocol + "//" + address
end

thank you, I haven't heard about splat parameters and it works perfectly for this case. Indeed, I've looked into the documentation and I found even shorter using capture parameters and regular expressions :
get %r{/add/(.+)} do
url = params[:captures]
end

or use:
url = request.fullpath[5..-1]

Related

Web API - pass double parameters to GET method

I have the following method:
[Route("GetEditorialRequestsByCoordinates/{lat:min(-90):max(90)}/{lng:min(-180):max(180)}")]
[AutomapperExceptionApiFilterAttribute]
public HttpResponseMessage GetEditorialRequestsByCoordinates(double lat, double lng)
{
}
It works fine when I call...
GET /v1/api/request/GetEditorialRequestsByCoordinates/48/2
But I want to pass double value like this:
GET /v1/api/request/GetEditorialRequestsByCoordinates/48.999/2.777
I got an error (404 not found). Seems, it can't find appropriate method by route.
I have tried to set route by way:
[Route("GetEditorialRequestsByCoordinates/{lat:double:min(-90):max(90)}/{lng:double:min(-180):max(180)}")]
...but it does not work either.
How can I fix it?
Simply adding a / to the end of the URL corrected it for me. Looks like the routing engine is viewing it as a 2.777 file extension, rather than an input parameter.
Additionally, it looks like you can register a custom route that automatically adds a trailing slash to the end of the URL when using the built-in helpers to generate the link.
he easiest solution is to just add the following line to your RouteCollection. Not sure how you would do it with the attribute, but in your RouteConfig, you just add this:
routes.AppendTrailingSlash = true;
For more details check here.
last of all max and min function works for integer
max: Matches an integer with a maximum value. {x:max(10)}
I think it does not work for double.

Parameters in route are not resolved

I have this configuration in the controller in Padrino
MyProject::App.controllers do
get '/' do
handlebars :index
end
get :file, :with => :tokenId do
tokenId = params[:tokenId]
[extra logic]
end
end
GET / works.
GET /file/abc doesn't.
GET /file/:tokenId works!
It looks like :token is not recognized as a parameter placeholder in the route definition.
I've tried
get "/file/:tokenId"
too but with no luck.
I can't find any information on any similar issue, anybody can help? Happy to add more information if needed.
Okay so I am unsure why the change made a difference but camelCase is generally considered poor syntax for variables in ruby.(Padrino may be calling a method such as underscore on your variable i.e.
"tokenID".underscore.to_sym
#=>:token_id
Using underscored_variables instead. (e.g. :tokenID becomes :token_id. This structure also allows for interacting with databases in a nicer way as well since your columns will have names such as token_id not tokenID.
There are uses for camelCasing in ruby and rails such as class naming and generators but trying keep all local and instance variables in lowercase underscore format.
I don't do much work in padrino so I am not 100% sure why this change helped but I am glad I could help.

How do I route based on a url parameter in sinatra?

I am using Sinatra and I want to use something like a referrer code in my urls that will somewhat control access and identify the provenance of a given URL.
/secret-code/rest/of/path
should be rejected if "secret-code" is not in a predetermined list.
I want to use route conditions
set(:valid_tag) { |tag| condition { tag === 'abcd' } }
get '/:tag', :valid_tag => params[:tag] do
'Hello world!'
end
but params is not in scope. Do I need to dispatch in the block? What is the best way to handle multiple routes without having to duplicate the tag checking logic in each one?
/secret/route1/
/secret/route1/blah
/secret/route2/
Is there a way to chain handlers? Can I do
get /:tag/*
# check :tag
redirect_to_handler(params[:splat])
By the sounds of things it looks like you're trying to make use of Sinatra's named parameters. Params is only in scope within the block:
get '/:secret_code/*' do
redirect_to_handler unless secret_codes.include? params[:secret_code]
end
The code above assumes you have a collection of 'secret_codes' that you're going to check with the secret_code from the URL.
(Answering my own question)
Sinatra matches the lexically first rule and you can pass onto the next matching rule using 'pass'. So something like this works as long as it is the first rule that would match.
get '/:tag/*' do
halt_if_bad_tag params[:tag]
pass
end
get '/:tag/route1' do
'hello world'
end

JSON::ParserError (399: unexpected token at

when I'm going to parse this:
Product = [{"Productname":"Acer 18.5" LED Monitor}]
with Ruby JSOn, its showing me the error JSON::ParserError (399: unexpected token at. I know this is for 18.5" in the string. How can I parse this string?
You have to give the string like this
Product = [{"productname":%q{"Acer 18.5" LED Monitor}}]
If you have an issue with Mongoid + Devise add this to your User model (bug page):
def to_key
id.to_s
end
In your /app/views/layouts/application.html.erb lines 5 and 6, change the first parameter from application to default.
I met the same problem, too for my situation, after changing it the problem was resolved happens on Windows. The parameter application works on the web server.

Parameter from the path includes query string in Sinatra. Is that correct?

I am running a Sinatra app under Passenger. I have an action which looks roughly like this:
get '/pic/:id' do
# do stuff ...
canonical_image_url = "/img/%d.jpg" % params[:id]
end
However I see my app is failing with the following exception
ArgumentError (invalid value for Integer(): "22?fill=width&width=512&sig=173798632b6ce659234a34c05324196c92b9a8ef")
which means that somehow the QS parameters are not being extracted from the path. Is this some kind of a weird escaping problem? (that some part of my app requests with a double-encoded query string) or is this a known problem? Or is it designed that way and path-params and QS params cannot be used at the same time?
A simpler way to write this (which will probably not help solve your problem, but is too long for a comment):
get '/pic/:id' do |id|
# do stuff ...
canonical_image_url = "/img/%d.jpg" % id
end

Resources