0

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, used 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?

ghr
  • 647
  • 4
  • 16

1 Answers1

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.

  • Interesting, thanks. Would [slimmer](https://github.com/alphagov/slimmer) still work with it in that case though? – ghr Mar 02 '12 at 16:43
  • Good question - I'm not sure how sinatra apps mounted within rails interact with middle wares. I know slimmer works with regular sinatra apps - we use it in https://github.com/alphagov/rummager but haven't tried it set up this way. If you have trouble perhaps you could stick your work on github? I'd be happy to have a play with it. – James Stewart Mar 02 '12 at 20:51
  • That would be amazing, thanks. I'll add them to github in the morning. – ghr Mar 05 '12 at 16:33
  • After some more hacking today, I think you're right about Middleware being the wrong way to go. I've added [the rails](https://github.com/garethrees/myrailsapp) and [rack](https://github.com/garethrees/myrackapp) apps to my Github. It [seems like its possible](http://railscasts.com/episodes/222-rack-in-rails-3) to `append_view_path` while inheriting from `ActionController::Metal` so I'm thinking that might be how to do it. – ghr Mar 06 '12 at 15:40
  • The other alternative (or possibly way to do this) is define a Railtie that creates a rails engine which sets the `append_view_path` – ghr Mar 06 '12 at 15:56
  • I'm not quite clear why you're trying to use the rails views from your rack/sinatra app? If you can't separate out the views then do you really want to make this a separate app? – James Stewart Mar 06 '12 at 22:00
  • What I ideally want to do is `yield` the sinatra `.erb` templates in to the rails layout. My "use case" is I have a Jobs board sinatra app which could be used anywhere. If I wanted to use it on its own, I could clone the repo and apply styles to the independent copy (and pull from upstream/master to get updates). If I wanted to use it as part of a larger site I could add the Gem to rails and then style the yielded template from rails. – ghr Mar 07 '12 at 10:49
  • [Like so](http://www.flickr.com/photos/grees/6961396617/sizes/l/in/photostream/)! – ghr Mar 07 '12 at 11:21