HttpHelpers routing methods in mounted rails engine results in uninitialized constant "controller name" - rails-engines

My environment:
Rails 3.2.8
Ruby 1.9.3p194
Fedora 16 x86_64
This problem seems specific to Rails Engines.
It seems that when using the HttpHelpers in a Rails Engine's routes file, I get "uninitialized constant Controller" when accessing a route via a browser. But, if I use a URL matcher in the Engine's routes file, it routes correctly.
Here's how I created a failing example:
$ rails plugin new my_engine --mountable
$ cd my_engine
$ rails g controller things index
$ rails s -p 3005
The controller generator uses the HttpHelpers#get method by default, so at this point the Rails Engine's config/routes.rb file looks like:
MyEngine::Engine.routes.draw do
get "things/index"
end
And, the test/dummy application's config/routes.rb file looks like:
Rails.application.routes.draw do
mount MyEngine::Engine => "/my_engine"
end
So, I should be able to hit http://locahost:3005/my_engine/things/index and see the Things#index view from the Engine. But, instead in the browser I see:
Routing Error
uninitialized constant ThingsController
If I manually change the Engine's config/routes.rb file to:
MyEngine::Engine.routes.draw do
#get "things/index"
match "things/index" => "things#index"
end
... and hit http://locahost:3005/my_engine/things/index, I see the correct Things#index view.
I noticed that when I use the HttpHelpers#get method in the Engine's config/routes.rb file, and run rake routes from the test/dummy directory, I see:
$ rake routes
my_engine /my_engine MyEngine::Engine
Routes for MyEngine::Engine:
things_index GET /things/index(.:format) things#index
But, if I change the Engine's config/routes.rb file to use the URL matcher method, I see:
$ rake routes
my_engine /my_engine MyEngine::Engine
Routes for MyEngine::Engine:
things_index /things/index(.:format) my_engine/things#index
Notice that when using the URL matcher, the controller and action are correctly namespaced under the engine. While, when using the HttpHelpers#get, the controller and action seem to be non-namespaced.
So, my question: Am I doing something wrong here? Or, is this a bug?
Note: I searched the rails issues and didn't see anything directly related to this. Though I did see several other engine and routing issues.

Related

Rails engine routes not loading

I have an application my_app, and an engine my_engine.
my_app routes:
Rails.application.routes.draw do
mount MyEngine::Engine => "/api"
end
my_engine routes:
MyEngine::Engine.routes.draw do
post "files/sync" => "files#sync"
end
From my_app, I run rails routes, and see the following:
Prefix Verb URI Pattern Controller#Action
my_engine_engine /api MyEngine::Engine
Routes for MyEngine::Engine:
As you can see, Routes for MyEngine::Engine: displays 0 results. I've tried every answer in the books about this issue, but nothing works.
Why are my engine routes not being listed by the app?
(Note that my_engine is a local gem — do I have to do something special to reload it possibly?)
One solution turned out to be changing:
gem 'my_engine', path: '/Users/me/Desktop/my_engine_gem'
to:
gem 'my_engine', path: '/Users/me/Desktop/my_engine_gem', require: 'my_engine'
This worked, even though placing require 'my_engine' in an initializer did not work. Not sure what the distinction is.

match ':controller(/:action(/:id))(.:format)' not found in config/routes.rb

Trying to follow the book Learning Rails 3 on a CentOS 6 Linux with rails 4 and ruby 2
And it repeatedly suggests me to uncomment a line in config/routes.rb:
Once again, you’ll need to enable routing for your controller. You’ll need to edit the config/routes.rb file. Remove the # that has been bolded below:
# match ':controller(/:action(/:id))(.:format)'
end
but there is no such line in the config/routes.rb - at least not after I run something like
# rails new guestbook
# cd guestbook/
# rails generate controller entries
# vim app/controllers/entries_controller.rb
# vim app/views/entries/sign_in.html.erb
# rails server
Is there maybe a new similar configuration line in Rails 4?
Example of regular route:
get 'products/:id' => 'catalog#view'
And root like this.
root 'home#index'
You can also add a catch-all route like this:
get ':controller(/:action(/:id))'

Rails 4 not showing routes in 'rake routes' but views are working

Pretty much as the title states, I have the following in my routes file:
root to: 'assets#index'
resources :assets do
member do
get :download
end
end
Yet my output for rake routes and visiting rails/info/routes are both simply:
Prefix Verb URI Pattern Controller#Action
root GET / assets#index
However the routes work fine in my views.
I also tried with bundle exec and I've updated to the latest version of bundle as some other posts suggested. It still works for my Rails 3 apps.
:assets is a reserved path in Rails. So you cannot really use it.

Listing 'rake routes' for a mountable Rails 3.1 engine

I'm working on a mountable engine for use with Rails 3.1, and I want to list the engine's routes.
I created the engine using:
$ rails plugin new rails_blog_engine --mountable
And edited the 'test/dummy/config/routes' file to read:
Rails.application.routes.draw do
mount RailsBlogEngine::Engine => "/blog"
end
...and 'config/routes' to read:
RailsBlogEngine::Engine.routes.draw do
resources :posts
end
I want to list the routes generated for ':posts', but it's not clear how I can do this. When I run 'rake app:routes', I get only the "/blog" route:
$ rake app:routes
rails_blog_engine /blog {:to=>RailsBlogEngine::Engine}
When I run 'rake routes', I get an error:
$ rake routes
rake aborted!
Don't know how to build task 'routes'
How can I see the routes for ':posts'? Can I do this without rewriting the relevant rake tasks?
In case people are missing it in the comments, as of Rails 3.2.2, you can now use
$ rake app:routes
If you copy code from the standard Rails 3.1.0 rake routes task into your Rakefile, and change the top part to read:
task :routes => 'app:environment' do
Rails.application.reload_routes!
all_routes = RailsBlogEngine::Engine.routes.routes
...replacing RailsBlogEngine with the name of your engine, then you can get a rudimentary list of routes by running:
rake routes
Note that in Rails 3.1.1 and later, you'll need a newer version of the rake routes task.
For rails 3.x engine, rake routes does not work under engine's root (that's why it needs some hack by copying rake file). However rake routes works under test/dummy (or spec/dummy if using rspec). It will list all the pathes which belong to the engine in development and other engines mounted.
For rails 3
desc 'Print out all defined routes inside engine match order, with names. Target specific controller with CONTROLLER=x.'
task engine_routes: :environment do
Rails.application.reload_routes!
app = ENV['ENGINE'] || "Rails.application"
all_routes = app.constantize.routes.routes
require 'rails/application/route_inspector'
inspector = Rails::Application::RouteInspector.new
puts inspector.format(all_routes, ENV['CONTROLLER']).join "\n"
end
Rails 4
desc 'Print out all defined routes inside engine match order, with names. Target specific controller with CONTROLLER=x.'
task engine_routes: :environment do
app = ENV['ENGINE'] || "Rails.application"
all_routes = app.constantize.routes.routes
require 'action_dispatch/routing/inspector'
inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, ENV['CONTROLLER'])
end
Then you can call like
$rake engine_routes ENGINE="IssueTracker::Engine"
in Rails 5, I could get the routes of the engine using the following command:
bundle exec rake app:routes
In rails 3.2X
If you are in you "host_app" and have mounted a engine you could probably list the routes by executing (should work out of the box):
bundle exec rake engine_name:routes

RoR: Sinatra producing error "uninitialized constant"

I'm new to Ruby on Rails (formerly and currently PHP expert) so forgive my ignorance but I'm trying to get Sinatra working as middleware to redirect some old urls since I tried the gem rack-rewrite and couldn't get that to work either.
I am using code samples from ASCIIcast so in my routes.rb I have the following:
root :to => HomeApp
(^ I'm redirecting the root only for testing)
In my lib folder I have home_app.rb
class HomeApp < Sinatra::Base
get "/" do
"Hello from Sinatra"
end
end
When I start the server (or if its already running) it produces the error:
routes.rb:10: uninitialized constant HomeApp
Which seems that it just isn't aware of the lib/home_app.rb file.
I have included Sinatra in my Gemfile and ran bundle install and confirms it is included.
I just want to reroute old urls from my old site to my new ruby app but can't get any of this middleware/rack stuff working. All documentation assumes you aren't a total newb or is for RoR pre-3.0.
You don't need to use Sinatra if you want to redirect some URLs. You can use the new redirect method. See the Rails Dispatch article.
match "/stories/:year/:month/:day/:name" => redirect("/%{name}")
constraints :user_agent => /iPhone/, :subdomain => /^(?!i\.)/ do
match "*path" => redirect {|params, req| "http://i.myapp.com/#{req.fullpath}" }
end
In your specific case, the problem is that the HomeApp class is not loaded. Either add the /lib folder to your load path changing application.rb
config.autoload_paths += %W( #{config.root}/lib )
or require the file.

Resources