问题
I'm trying to use a Sinatra app as middleware in my Rails app.
I've tested a basic Sinatra app in the /lib
folder of the Rails app, use
d the middleware and set a route. That worked fine.
What I want to be able to do is extract the Sinatra app and include it as a gem. That way I can run the Sinatra app independently, or use it in multiple Rails apps.
Sinatra App
# myrackapp/lib/myrackapp.rb
module Myrackapp
class Application < Sinatra::Base
set :root, File.dirname(__FILE__)
get "/" do
"Rack Home"
end
get '/rackroute' do
"Hello, Rack Page"
end
end
end
Myrackapp
also has a gemspec
– nothing interesting there, but I can post if necessary.
Rails App
# Gemfile
gem 'myrackapp', path: "/Users/gareth/Code/myrackapp"
-
# config/application.rb
module Myrailsapp
class Application < Rails::Application
...
config.middleware.use "Myrackapp::Application"
end
end
-
# config.routes.rb
root :to => 'pages#show', :id => 'home'
mount Myrackapp::Application => "/rackapp"
Here's my rake middleware
output:
rake middleware
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x141ded4>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use ActionDispatch::Head
use Rack::ConditionalGet
use Rack::ETag
use ActionDispatch::BestStandardsSupport
use Myrackapp::Application
run Myrailsapp::Application.routes
When I go to http://myapp.dev/rackapp
I get Myrackapp
's root path - correct behaviour
When I go to http://myapp.dev/rackapp/rackroute
I get Myrackapp
's /rackroute
path - again, correct behaviour
The Problem
When I go to http://myapp.dev
in the browser I get directed to the Myrackapp
's root path.
When I included the Sinatra app directly in my Rails app visiting http://myapp.dev
rendered the correct pages#show
action.
What can I do to get the Sinatra app to not hijack the root path of Rails?
回答1:
You don't actually need to include the Sinatra app as middleware to do what you want.
Including it as middleware will mean that all requests are routed through it, which you don't want/need in order to make it supply the routes.
If you want to add the routes automatically when you include the gem in a rails app you could add a railtie that adds routes to the application. I can't remember off the top of my head what that looks like, but it should be pretty straightforward.
来源:https://stackoverflow.com/questions/9533830/sinatra-rack-middleware-hijacks-root-url