Sinatra: access to optional parameter - ruby

In code like this,
get '/posts.?:format?' do
# ...
end
How can I get the format that was requested?

Look into the params hash as in a no-optional param situation:
params[:format]

Related

Ruby's Faraday - Send optional parameters in get method

I have an endpoint with multiple optional parameters.
def get_customers(params=nil)
if params.nil?
customer_url = "#{#url}/customers"
# call api
response = connection.get(customer_url)
else
# I do not know how to write this part
end
end
Could you please help me in order to write a call to and endpoint with optional parameters. The params argument is a hash (key, pair value). The query can have 8 parameters. I do not know how to concatenate the params to the url. I am stack in this section. I am a rookie at ruby and faraday.
Thanks in advance
You don't have to concatenate params with the url on your own. Faraday can accept a hash of params (or nil). You can pass them to the get method like so:
response = connection.get(customer_url, params)
Have into the "GET, HEAD, DELETE, TRACE" section of the documentation for more examples.
Side note: you don't event have to concatenate url and the path. You can pass them as separate arguments.

Using parsed response in separate GET call

I'm new to Ruby and API, so my apologies if this is super simple...
I need to have script that will first POST to initiate the creation of an export file, and then have a GET call to retrieve the file. The GET call needs to use part of the POST json response.
I'm using the httparty gem.
I think I need to create a variable that equals the parsed json, and then make that variable part of the GET call, but I'm not clear on how to do that.
Help is appreciated.
require 'httparty'
url = 'https://api.somewhere.org'
response = HTTParty.post(url)
puts response.parse_response
json response:
export_files"=>
{"id"=> #####,
"export_id"=> #####,
"status"=>"Queued"}}
In my GET call I need to use the export_id number in the url.
HTTParty.get('https://api.somewhere.org/export_id/####')
As described in the comments but a bit more verbose and skeleton for error:
require 'httparty'
require 'json'
url = 'https://api.somewhere.org'
response = HTTParty.post(url)
if hash = JSON.parse(response.body)
if export_id = hash[:export_files][:export_id]
post = HTTParty.post("https://api.somewhere.org/export_id/#{export_id}")
end
else
# handle error
end

Sinatra: params hash cannot be merged

I want to merge a hash with default parameters and the actual parameters given in a request. When I call this seemingly innocent script:
#!/usr/bin/env ruby
require 'sinatra'
get '/' do
defaults = { 'p1' => 'default1', 'p2' => 'default2' }
# params = request.params
params = defaults.merge(params)
params
end
with curl http://localhost:4567?p0=request then it crashes with
Listening on localhost:4567, CTRL+C to stop
2016-06-17 11:10:34 - TypeError - no implicit conversion of nil into Hash:
sinatrabug:8:in `merge'
sinatrabug:8:in `block in <main>'
When I access the Rack request.params directly it works. I looked into the Sinatra sources but I couldn't figure it out.
So I have a solution for my actual problem. But I don't know why it works.
My question is: Why can I assign param to a parameter, why is the class Hash but in defaults.merge params it throws an exception?
Any idea?
This is caused by the way Ruby handles local variables and setter methods (i.e. methods that end in =) with the same name. When Ruby reaches the line
params = defaults.merge(params)
it assumes you want to create a new local variable named params, rather than use the method. The initial value of this variable will be nil, and this is the value that the merge method sees.
If you want to refer to the method, you need to refer to it as self.params=. This is for any object that has such a method, not just Sinatra.
A better solution, to avoid this confusion altogether, might be to use a different name. Something like:
get '/' do
defaults = { 'p1' => 'default1', 'p2' => 'default2' }
normalized_params = defaults.merge(params)
normalized_params.inspect
end
Your code is throwing an error because params is nil when you make this call defaults.merge(params). I assume you are trying to merge defaults with request.params, which should contain the parameters from your GET.
Change this line
params = defaults.merge(params)
to this
params = defaults.merge(request.params)
I found this in rack gem
http://www.rubydoc.info/gems/rack/Rack/Request#params-instance_method
It seems you can retrieve GET and POST data by params method but you can't write in it. You have to use update_param and delete_param instead.

Sinatra URL Matching with question mark?

Is there a way to match urls with Sinatra using question mark?
get '/:id?inspect' do
# ...
end
get '/:id?last' do
# ...
end
get '/:id' do
# ...
end
I tried escaping the question mark \?, regex etc, but none of those worked.
I don't want to retrieve the value of inspect or last. I only want to know if they were supplied in the url.
Is that possible?
You can’t directly do what you want. When describing the route, Sinatra treats ? as defining an optional parameter, and doesn’t provide a way to escape it.
In a url a ? separates the path from the query string, and Sinatra only uses the path when matching routes. The contents of the query string are parsed and available in params, and the raw string is available as request.query_string.
Your url scheme seems rather unusual, but one possibility if you want to avoid checking the query_string in the actual route could be to create a custom condition to apply to the routes, and check in there:
set(:query) { |val| condition { request.query_string == val } }
get '/:id', :query => 'inspect' do
# ...
end
get '/:id', :query => 'last' do
# ...
end
get '/:id' do
# ...
end
A standard route is not defined by query parameters and should not be. Why don't you use a if construct on the params in the get /:id route?
I also suggest that when you want to set a query parameter in the request you set it like this: /:id?inspect=true (provide a dummy value)

Getting only key value back from MongoMapper to_json result

Sorry for the newbie question but still very new to Ruby and Mongo.
Not 100% sure what I am missing, but how would I get just the value back
from "url" in the following json result?
[{"url":"www.google.com"}]
So I want something like if I do a
puts url_var
it should just display www.google.com
MongoMapper code to get URl from Mongo
redirect_url = Surl.all(:url_key => "#{urlkey}")
myjson = redirect_url.to_json(:only => [:url])
puts redirect_url
gives me
[{"url":"www.google.com"}]
if I do something like
redirect_url.each do |key,value|
puts key
puts value
end
key is still the full json string and value is empty.
Surely I must be missing something really basic here
Okay, I assume Surl is a model of yours, which has at least these fields url_key and url, so to access the url you don't have to convert the result to json and then fetch to key, but you can access it directly.
Surl.all returns an array (check the mongo mapper docs), if you want a single result use Surl.find_by_url_key(urlkey). Now you can access the url directly by using puts redirect_url.url
redirect_url = Surl.find_by_url_key(urlkey)
puts redirect_url.url # => "www.google.com"
Be sure to read up on http://mongomapper.com/documentation/plugins/dynamic-querying.html and http://mongomapper.com/documentation/plugins/querying.html, to understand the results and differences.

Resources