Namespaced controller routing in Rails 3 without resources - ruby-on-rails-3

I'm migrating an application from Rails 2 to Rails 3.
We have multiple namespaced controllers with different namespaces.
As they are not RESTfull I don't want to use resource routing, instead I would like to have an old Rails 2 like match ':controller/:action' that picks up namespaced controllers.
In my routes.rb I have
# Install the default route as the lowest priority.
match ':controller(/:action(/:id(.:format)))'
match ':controller(/:action(/:id(.:format)))', :controller => /[^\/]+\/[^\/]+/
rake routes reports
/:controller(/:action(/:id(.:format))) :controller#:action
/:controller(/:action(/:id(.:format))) (?-mix:[^\/]+\/[^\/]+)#:action
Still a request to /config/companies/index fails
ActionController::RoutingError (No route matches [GET] "/config/companies/index"):
What am I doing wrong? Is there another way to get namespaced routes with dynamic segments? When I try to use namespace and a match with a dynamic segment together it throws an error.
:controller segment is not allowed within a namespace block

OK I found the problem.
Config is a reserved constant in Rails, it points to RbConfig. My match condition actually works but tries to call RbConfig::CompaniesController which of course does not exist.
When I tried to add
match '/:controller(/:action(/:id(.:format)))', :controller => /config\/[^\/]+/
the error was
ActionController::RoutingError (uninitialized constant RbConfig::CompaniesController)
Solution: rename the app/controllers/config -> app/controllers/configuration (and the views folder) and add a redirect to the routing to handle legacy links.
match '/config/*path' => redirect("/configuration/%{path}")

Related

Routing error rails 3

I have a Rails 2.3.5 app with many controllers, models etc. which I'm trying to upgrade to Rails 3.2.21. I'm having some troubles with my routes. I tried to follow the Rails 3 new routing format but it doesn't seem to work. I'm getting two problems (which I guess all indicate one fundamental issue with my routing):
In the root ('/') I'm getting the generic "Welcome abroad" Rails
page. My routes (see below) have defined routing for root.
For some controllers I get No route matches [GET] "/study" message. My route shows this route, but for some reason doesn't define the GET method.
Here's my config/routes.rb code:
Myapp::Application.routes.draw do
root :to => 'study#index'
match 'login' => 'login', :protocol => 'https://'
resources :study_maps do
get :clone, :on => :member
end
# Route report create actions to the report controller
match 'report/create', :as => 'report'
match ':controller(/:action(/:id))(.:format)'
end
If I'm running rake routes I'm getting:
root / study#index
login /login(.:format) login#login {:protocol=>"https://"}
clone_study_map GET /study_maps/:id/clone(.:format) study_maps#clone
study_maps GET /study_maps(.:format) study_maps#index
POST /study_maps(.:format) study_maps#create
new_study_map GET /study_maps/new(.:format) study_maps#new
edit_study_map GET /study_maps/:id/edit(.:format) study_maps#edit
study_map GET /study_maps/:id(.:format) study_maps#show
PUT /study_maps/:id(.:format) study_maps#update
DELETE /study_maps/:id(.:format) study_maps#destroy
report /report/create(.:format) report#create
/:controller(/:action(/:id))(.:format) :controller#:action
Here's my StudyController#index code:
require 'myapp/studymgr'
require 'project_user'
require_dependency 'myapp/controller_extensions/report_manager'
class StudyController < ApplicationController
include PaginatorController
before_filter(:authenticate, :except => [:todo])
before_filter(:authorize,
:only => [:update, :destroy, :edit, :prune, :select_experiments ])
def index
#tags = Stag.find(:all).collect { |stag| stag.tag }
...
#include_ext = true
end
end
Can someone advise on what I'm missing?
Finally found a solution - my views had .rhtml extension. I found that this format is no longer supported under Rails 3 (What is the difference Between .erb , .rhtml and .html.erb?), so I changed all views extensions to .html.erb and then the routes worked with no need to specify explicit resource for each controller, just using the generic route: match ':controller(/:action(/:id))'.
As for the issue in the root route (#1 above), where I always got the Rails "Welcome abroad" page, despite having explicit route in my routes.rb, turns out I had to remove public/index.html which is loaded for root by Rails, and then my view was loaded.

Remove "index" from url in Rails

I'm currently defining routes for my pages in the following manner:
get "home/index"
get "photo/index"
get "project/index"
get "home/about"
root :to => 'home#index'
However, I can only seem to be able to create a link to the photo/project index pages by using:
link
link
In the URL, the "index" part also shows up. I can't simple use /photo in the a link, because rails throws a routing error:
No route matches [GET] "/photo"
How would I create a route match for this?
match "/photo", to: "controller#action"
http://guides.rubyonrails.org/routing.html#connecting-urls-to-code
The best answer is to use match. Don't forget to include via to preserve your restriction on the http method:
match "/photo", to: "controller#action", :via => 'get'

URL helper for a post route in a resource

I have a resourceful route, with a post route nested within it:
resources :groups, :only => [:index, :show] do
post 'send_audit_reminder', :on => :member
end
If I run rake routes, this route shows up just fine:
send_audit_reminder_group POST /groups/:id/send_audit_reminder(.:format)
{:controller=>"groups", :action=>"send_audit_reminder"}
However, I can't seem to figure out how to refer to the send_audit_reminder URL for a given route. I've tried send_audit_reminder_group_path(#group) and send_audit_reminder_url(#group), which both give me the following error:
No route matches {:controller=>"groups", :action=>"send_audit_reminder"}
As you can see from rake routes, there is indeed a route that matches those parameters, and there is also a matching method on the controller.
How can I find the path or URL for this route? I would like not to hard code it, since our apps are deployed to subdirectories on the same virtual host, so a hard-coded absolute path won't work.
And where would I look for documentation or information on this in the future? Since these path and URL helper methods are generated from my routes, I obviously can't look for documentation, and while rake routes tells me that the route is there, it doesn't appear to be there when I try and get the URL.
It might be that you're missing the placeholders and it can't route because of that. The following should work based on your definition:
send_audit_reminder_group_path(group)
Any time you see identifiers like :id or :group_id in your route, you must supply them unless they are in brackets, which declares them as optional, as is the case here with :format. The arguments need to be supplied in the same order they are declared. For this:
/example/:user_id/groups/:id
The arguments to this route would be user_id and id and both must be supplied. Generally with routes you can either use a literal number or string, or a model that supports to_param as all ActiveRecord::Base-derived ones do.
This all stems from declaring with :member, meaning it is specific to a particular record, and not :collection where that is omitted. The Rails Routing Guide explains more.

Routing problem in ruby on rails

I am new to ruby on rails.
I used the command 'rails generate controller Courses new'
Then, I edited routes.rb file with:
resources :courses
match '/courses', :to => 'courses#new'
When I access http://0.0.0.0:3000/courses. I get an error:
Unknown action
The action 'index' could not be found for CoursesController.
I think i am missing something. Please help
Thanks.
The line
resources :courses generates the routes for courses like so:
/courses -> coursescontroller#index
/courses/:id -> coursescontroller#show
...
and so on. This is known as 'restful routes'.
If you do not want to direct a url of form 'courses.html' to the 'index' action of your courses controller, but to the 'new' action of your courses controller (which would be highly unusual, by the way), just remove the first line from your routes.rb.
If you want to see what routes you have defined, just do
rake routes
from your rails app directory.
You could use this instead:
resources :courses, :except => :index
match '/courses', :to => 'courses#new'
The except option takes a symbol or an array of actions in the controller you do not want to define resource routes for. In this case, we turn off the route for the index action, /courses/.
Next, we define the same route that would have been defined for the index action, but point it at CoursesController#new.
Put your "match" line before your "resources" line.

rails routes with flash

I fixed RoutingError in rails 3 using this link. I wanted to redirect users to root page so I added:
match '*a', :to => 'homes#index'
to my routes.rb.
Question is: can I define flash[:error] message in this 'match' line to be displayed on target page?
Regards,
Mateusz
This is similar to Redirect and raise flash message when catch-all in routes
But I did run into this problem and it was giving me an issue because I was using MATCH and when I used GET, the alert wouldn't flash. Eventually I found a working solution using the thread above and applying GET in another manner.
match '*path' => redirect{ |p, req| req.flash[:alert] = "The page you requested is not valid."; '/' }, via: [:get]
This is what I ultimately came up with, via: [:get] being key to making everything work.
And remember to place such code at the end of your routes.rb