toy
toy

Reputation: 12141

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

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?

Upvotes: 6

Views: 15556

Answers (3)

Morgan
Morgan

Reputation: 20514

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

Upvotes: 15

matt
matt

Reputation: 79733

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.

Upvotes: 4

ch4nd4n
ch4nd4n

Reputation: 4197

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

Upvotes: 5

Related Questions