Routing broken in mountable engines #5370

Closed
mmell opened this Issue Mar 10, 2012 · 1 comment

Comments

Projects
None yet
2 participants

mmell commented Mar 10, 2012

Routing to a resource in a mountable engine does not work correctly. Requests for the mountable resource only connect if there is a root route in the engine. Requests for other resources in the engine always route to the root resource.

The following demonstration of these issues can be performed in a couple of minutes.

Setup the "MainApp" and the plugin/gem "MyMountableApp"

# Work in a sub-directory
mkdir MountableRoutesDemo
cd MountableRoutesDemo/
# Confirm current rails version
rails -v
  #=> Rails 3.2.2
rails new MainApp
# Create a directory to access gems via :path
mkdir gem_repository
cd gem_repository/
# Create the mountable app
rails plugin new MyMountableApp --mountable
cd MyMountableApp/
# Create the Person mountable resource
rails generate scaffold person id:integer name:string
cd ../../MainApp/
# Update the Gemfile to bundle the mountable app
echo 'gem "my_mountable_app", :path => "../gem_repository"' >> Gemfile
# Configure the main app to mount the mountable resource (People)
vim config/routes.rb

Paste, save and exit the editor: mount MyMountableApp::Engine => "/people"

bundle
# Copy the mountable app migration
rake my_mountable_app:install:migrations
rake db:migrate
rails server -p3001

At this point we have MainApp running on port 3001 which includes MyMountableApp from the local gem_repository.

Issue #1: the MyMountableApp People resource is not accessible

# In new Terminal (or a web browser)
curl http://0.0.0.0:3001/people
# The server log (in the first Terminal window) shows
  #=> ActionController::RoutingError (No route matches [GET] "/people")

However, rake routes shows that the request for /people should find a match

rake routes
  #=> my_mountable_app  /people MyMountableApp::Engine
  #=> Routes for MyMountableApp::Engine:
  #=>    people GET    /people(.:format)          my_mountable_app/people#index

The above scenario is the simplest arrangement of a mountable engine within a Rails application and it clearly demonstrates that routing is broken.

Curiously, adding a root route to MyMountableApp fixes the issue.

vim ../gem_repository/MyMountableApp/config/routes.rb

Paste, save and exit the editor: root :to => 'people#index'

# (Restart server in Terminal #1)
curl http://0.0.0.0:3001/people
# Success Status 200

Simply adding the root route in the engine made the People resource available.

Issue #2: requests for any other mounted resource (Toys) are routed to the root mounted resource (People)

cd ../gem_repository/MyMountableApp/
# Create a second resource, Toys, in the mountable application
rails generate scaffold toys id:integer person_id:string name:string
cd ../../MainApp
# Copy the mountable app migration
rake my_mountable_app:install:migrations
rake db:migrate
# Configure the main app to mount the second mountable resource (Toys)
vim config/routes.rb

Paste, save and exit the editor: mount MyMountableApp::Engine => "/toys"

# (Restart server in Terminal #1)
curl http://0.0.0.0:3001/toys
# The server log (in the first Terminal window) shows
#=> Started GET "/toys" for 127.0.0.1 at 2012-03-10 10:43:10 -0800
#=> Processing by MyMountableApp::PeopleController#index as HTML

The request for /toys was routed for processing to the PeopleController. Routing should have triggered processing of the ToysController.

Owner

pixeltrix commented Mar 10, 2012

I think you've slightly misunderstood the rake routes output - the engine's routes are available under the mount point, so given the following routes:

# main_app/config/routes.rb
mount MyMountableApp::Engine => '/people'

# my_mountable_app/config/routes.rb
resources :people

then the my_mountable_app/people#index route is actually at /people/people and there's no actual route at /people. That's why adding the root route makes it work. Similarly, adding the toys resource and mounting it under /toys just makes the same routes available under a different path. If you want the people resource available at /people you need to mount it under /.

@pixeltrix pixeltrix closed this Mar 10, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment