How do I config.ru properly in modular Sinatra application.?

14,317

Solution 1

With URLMap you specify a base url where the app should be mounted. The path specified in the map is not used when determining which route to use within the app itself. In other words the app acts as if it's root is after the path used in URLMap.

For example, your code will respond to the following paths:

  • /: will be routed to the / route in MyApp

  • /another: will go to the / route in AnotherRoute. Since AnotherRoute extends MyApp this will be the same as / in MyApp (but in a different instance).

    URLMap sees /another and uses it to map to AnotherRoute, stripping this part of the request from the path. AnotherRoute then only sees /.

  • /another/another: will be routed to the two /another routes in AnotherRoute. Again, the first another is used by the URLMap to route the request to AnotherRoute. AnotherRoute then only sees the second another as the path.

    Note that this path will respond to both GET and POST requests, each being handled by the appropriate block.

It's not clear what you're trying to do, but I think you can achieve what you want by running an instance of AnotherRoute, with a config.ru that is just:

run AnotherRoute.new

Since AnotherRoute extends MyApp, the / route will be defined for it.

If you're looking for a way to add routes to an existing Sinatra application, you could create a module with an included method that adds the routes, rather than use inheritance.

Solution 2

app.rb

class MyApp < Sinatra::Base
  get '/' 
  end
end

app2.rb If you want two separate files. Note this inherits from Sinatra::Base not MyApp.

class AnotherRoute < Sinatra::Base
  get '/'
  end

  post '/'
  end
end

The config.ru

require 'bundler/setup'
Bundler.require(:default)

require File.dirname(__FILE__) + "/lib/app.rb"
require File.dirname(__FILE__) + "/lib/app2.rb"


map "/" do
    run MyApp
end

map "/another" do
    run AnotherRoute
end

Solution 3

You could write this as

class MyApp < Sinatra::Base
  get '/' 
  end
  get '/another'
  end

  post '/another'
  end
end

in config.ru

require './my_app'
run MyApp

Run:

rackup -p 1234

Refer to documentation at http://www.sinatrarb.com/intro#Serving%20a%20Modular%20Application

Share:
14,317
toy
Author by

toy

This space is intentionally left blank.

Updated on July 17, 2022

Comments

  • toy
    toy almost 2 years

    I'm trying to use subclassing style in Sinatra application. So, I have a main app like this.

    class MyApp < Sinatra::Base
      get '/' 
      end
    
      ...
    end
    
    class AnotherRoute < MyApp
      get '/another'
      end
    
      post '/another'
      end
    end
    
    run Rack::URLMap.new \ 
      "/"       => MyApp.new,
      "/another" => AnotherRoute.new
    

    In config.ru I understand that it's only for "GET" how about other resources (e.g. "PUT", "POST")? I'm not sure if I'm missing someting obvious. And also if I have ten path (/path1, /path2, ...) do I have to config them all in config.ru even though they are in the same class?