How to mount a Sinatra application inside another Sinatra app?
Take a look at https://stackoverflow.com/a/15699791/335847 which has some ideas about namespacing.
Personally, I would use the config.ru with mapped routes. If you're really in that space between "should this be a separate app or is it just helpful to organize it like this" it allows that, and then later you can still farm off one of the apps on its own without changing the code (or only a little). If you're finding that there's a lot of duplicated set up code, I'd do something like this:
# base_controller.rb
require 'sinatra/base'
require "haml"
# now come some shameless plugs for extensions I maintain :)
require "sinatra/partial"
require "sinatra/exstatic_assets"
module MyAmazingApp
class BaseController < Sinatra::Base
register Sinatra::Partial
register Sinatra::Exstatic
end
class Blog < BaseController
# this gets all the stuff already registered.
end
class Foo < BaseController
# this does too!
end
end
# config.ru
# this is just me being lazy
# it'd add in the /base_controller route too, so you
# may want to change it slightly :)
MyAmazingApp.constants.each do |const|
map "/#{const.name.downcase}" do
run const
end
end
Here's a quote from Sinatra Up and Running:It has some good examples of using this technique (and others). Since I'm in shameless plug mode I recommend it, even though I've nothing to do with it! :)Not only settings, but every aspect of a Sinatra class will be inherited by its subclasses. This includes defined routes, all the error handlers, extensions, middleware, and so on.
Mount Sinatra app inside a rails app and sharing layout
You basically need to do two things:
You need to tell the Rails router that a certain URL path is to be handled by another Rack app (in your case a Sinata app). This can be done by adding this to your routes.rb:
match "/sinatra" => MySinatraApp, :anchor => false
Having done that, you can create your app like so:class MySinatraApp < Sinatra::Base
get "/" do
"Hello Sinatra World"
end
end
The second step now is to tell your Sinatra app to use the rails layout which by default lives in app/views/layouts/application.html.erb
for Rails 3.1. by default, Sinatra uses ./views/layout.ext
(with ext
being the extension of your chosen template system). So you basically, have to tell Sinatra to- use another directory to find views and layouts instead of the default
./views
- use another template file as the default layout.
set :views, "/path/to/your/railsapp/views"
set :erb, layout => :"layout/application" # or whatever rendering engine you chose
Multiple Sinatra apps using rack-mount
I think you'll prefer Rack::URLMap - it will probably look something like this:
run Rack::URLMap.new("/" => App.new,
"/api" => Api.new)
That should go in your config.ru
file. Mounting a Sinatra app and all its routes in a Rails application
So the problem ended up being that I missed the leading /
before widgets in the get route, so it wasn't being routed correctly.
Mounting Sinatra app on rails 5
I was able to resolve this with a newer version of sinatra.
gem 'sinatra', '2.0.0.beta2'
rackup mounting apps vs rails mounting for sinatra apps
Interesting there is any significant difference apart from the fact that in the latter part(application mounted using rackup)
any requests to
/url1
/url2
would be server directly from the mounted rack application without actually passing the request in the middleware stack of rails and then detect valid rack application for the given mounted path .
Which would happen in first part where your sinatra application is mounted inside Rails defined in routes.rb
of your file
So I your are trying to mount
your sinatra application in routes.rb
instead of config.ru
then consider the fact that your request would be passed all along rails middleware stack
where routing middleware detect the appropriate path as passed the request to desired sinatra application
A Simple check You can do for this is try hitting your path i.e /url1
or /url2
in both the technique and you would see sinatra application routes.rb would log the request in your rails application whereas the other one would not
Hope this help
How to split a Sinatra app with different scopes?
I don't think this is achievable in the way you are trying. If you have methods with similar names in different modules mixed into a single class the last just wins.
So in this case I would create a modular app combined with a config.ru to setup your application.
class OneRegister < Sinatra::Base
# helpers here
end
class SecondRegister < Sinatra::Base
# helpers here
end
In config.ruapp = Rack::URLMap.new(
'/one-endpoint' => OneRegister,
'/second-endpoint' => TwoRegister
)
run app
No you helpers are scoped to a single class.
Related Topics
Can't Install Debugger Gem - Rails - MAC Osx Mavericks
Ruby on Rails Private Link Sharing: Google Docs Style
How to Make Fish Shell Use an Rvm Ruby by Default
Good Forms Helpers for Sinatra
Ubuntu 10 Ruby 1.9 Rails 3: No Such File or Directory
Rails Has_Many Through Form with Additional Attributes
Camelcase Instead of Snake_Case in Rails Db
Use a String to Access a Local Variable by Name
Ruby Linkify for Urls in Strings
Inspect or Clean Up The Working Tree Error When Installing Ruby 2.1.3 on MAC Os X 10.9.5
Rails + Mongoid - Don't Return Nil Values in JSON
How to Calculate a String's Width in Ruby
Strong Parameters with Nested Hash
Why Does Including This Module Not Override a Dynamically-Generated Method
Facebook Redirect Url in Ruby on Rails Open Ssl Error