Rails engine routes not loading - ruby-on-rails

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.

Related

Ruby on Rails API namespace as default path

I am setting up my Rails API server following this tutorial: building-awesome-rails-apis-part-1
Everything works well, except the part that mentions that it is not necessary to indicate the namespace in the route. Eg.
Now our URls look like: http://api.example.com/v1/people or just
http://api.example.com/people if you don’t use the version, it
doesn’t interfere with your regular people routes, and it looks great.
When I call http://api.mydomain.com/v1/therapists/ it works, but when I try to omit the v1 namespace in the URL it's not working, do I need to do any extra configuration?
I'm using Rails 6.0.3.4
This is my specific routes.rb file:
Rails.application.routes.draw do
namespace :api, :path => "", :constraints => {:subdomain => "api"} do
namespace :v1 do
resources :therapists do
resources :appointments
end
end
end
end
Solution
As zhisme suggested, I used rack-rewrite gem to do what I wanted.
First, I added the gem to my Gemfile:
gem 'rack-rewrite', '~> 1.5', '>= 1.5.1'
After that I added the configuration in config/application.rb file
config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
rewrite '/therapists', '/v1/therapists'
end
And it worked.
In order to achieve this, you will need to insert inside Rack code. There is a gem rack-rewrite that can do redirects before Rails code execute, thus before rails routes resolving. Check their README for installation.
so modifying README example to your question, you can do something like
config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
rewrite '/api/therapists/appointments', '/api/v1/therapists/appointments'
end
or you can make redirects to give your api consumers to know that correct url is a bit different
config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
moved_permanently '/api/therapists/appointments', '/api/v1/therapists/appointments'
end
There is quite good article describing different solutions, take a look for more details.
If you omit the v1 namespace in the URL, you must also remove it from your routes.rb file.
The quote from the tutorial stated "or just http://api.example.com/people if you don’t use the version", meaning if you don't include the v1 namespace in the routes.rb file.

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.

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

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.

How to add a route to a ruby gem

I've been creating a gem and I need to create a route that maps to a controller in the gem.
I have a file ( config/routes.rb ) which looks like this:
Rails.application.routes.draw do
match "rest/*path" => "bconnected/apis#rest"
end
My controller lives in *app/controllers/bconnected/apis_controller.rb*
My gemspecs file includes all of these files.
I run gem build, and gem install.
I include my gem in the rails Gemfile but when I try to hit that URL I get:
No route matches [GET] "/rest/test"'
Do I need to do anything special for Rails to read my routes.rb file from the gem?

why doesn't this routing work on heroku but works locally?

I have the following in my routes.rb file for Rails 3:
13 namespace :user do
14 root :to => "users#profile"
15 end
I get this error on heroku:
ActionController::RoutingError (uninitialized constant User::UsersController):
I already restarted the application.
I am doing this because I am using devise and this is what it says on the wiki:
https://github.com/plataformatec/devise/wiki/How-To:-Redirect-to-a-specific-page-on-successful-sign-in
The problem is that Rails is expecting there to be a controller within a module called Users because that's what namespace :user infers. Perhaps you meant to use scope instead of namespace?
scope :path => "user" do
root :to => "users#profile"
end
Note: in this situation if you've only got one route it would not be wise to use scope, but if you've got multiple ones with the /user prefix then it would be fine to. If you only had one, I would do this instead:
get '/user', :to => "users#profile"
Heroku environments run in production mode. When you run locally, you run in development mode, which accounts for at least one difference. Try this instead:
RAILS_ENV=production bundle exec rails s
and see if you notice the same error.

Resources