3

I have a list of words in a list, and I want to handle get requests to any of them (and respond the same way).

@words = ["foo","bar"....etc]

One of the ways I thought I could do this is to loop through the list and have a get directive generated for each word when sinatra is launched.

@words.each do |word|
    get word do
       # what to do
    end
end

that doesn't work, but something in that fashion, maybe.

Another way of doing it might be responding to get %r{/(.+)} and then doing some processing inside there to see if it matches anything in the list and respond accordingly, but I'm interested nonetheless to see if there's a way I can do it as described above.

Phrogz
  • 296,393
  • 112
  • 651
  • 745
hsiu
  • 37
  • 4

2 Answers2

4
  1. What you wrote does work, with a very minor change. For example:

    require 'sinatra'
    %w[foo bar].each do |word|
      get "/#{word}" do
        "You said #{word}!"
      end
    end
    
    $ curl http://localhost:4567/bar
    You said bar!
  2. Instead of a catch-all regex route, you can craft a custom regexp dynamically to match only the words you want to match:

    require 'sinatra'
    words = %w[foo bar]
    route_re = %r{^/(#{words.join '|'})$}i # case-insensitive
    p route_re
    #=> /^\/(foo|bar)$/i
    
    get route_re do |name|
      "You said #{name}!"
    end
    
    $ curl http://localhost:4567/FoO
    You said FoO!
    
    $ curl -I http://localhost:4567/jim
    HTTP/1.1 404 Not Found
    X-Cascade: pass
    Content-Type: text/html;charset=utf-8
    Content-Length: 413
    Connection: keep-alive
    Server: thin 1.2.7 codename No Hup
Phrogz
  • 296,393
  • 112
  • 651
  • 745
2

Depending on what you need, this might be enough:

get '/:word' do
  # check if params[:word] is in your list
  # and respond accordingly
  if @words.include?(params[:word])
      "yeeah"
  else
      pass
  end
end

But keep in mind that this route matches everything.

scable
  • 4,064
  • 1
  • 27
  • 41