Rails routing error help No route matches - ruby-on-rails

I get a this eror when visit the url http://localhost:3000/admin/login:
ActionController::RoutingError in Admin/login#index
/app/views/admin/login/index.rhtml where line #18 raised:
No route matches {:action=>"login_in_user", :controller=>"admin/login"}
Extracted source (around line #18):
15:
16: <h2>Login</h2>
17: <div class="spacer"> </div>
18: <%= form_tag(:action => "login_in_user") %>
19:
20:
21: <p>
Here is my Admin login controller class in controllers/admin:
class Admin::LoginController < ApplicationController
My route file:
namespace :admin do
resources :login
end
match ':controller/service.wsdl', :action => 'wsdl'
# Install the default route as the lowest priority.
match ':controller/:action/:id'
I do have a action named: login_in_user
UPDATE OLD ROUTE FILE:
map.connect ':controller/service.wsdl', :action => 'wsdl'
# Install the default route as the lowest priority.
map.connect ':controller/:action/:id'

The problem is that you don't have any mapping for the url you're trying to create a link to. login_in_user is not one of the standard resource actions, so you need to add it explicitly. The relevant routes.rb entry in your case currently looks like this:
namespace :admin do
resources :login
# and other stuff...
end
It could work if you did something like this:
namespace :admin do
resources :login do
collection do
post :login_in_user
end
end
However, remember that resources are not a good fit for all controllers. Creating a resources entry generates routes that map to seven specific actions, suitable for managing a resource. A "LoginController" with an action called "login_in_user" doesn't sound like a resource to me. It's possible you're simply trying to create a controller with specific paths to log in through different means. In that case, maybe you could create the routes like so:
namespace :admin do
post 'login/login_in_user' => 'login#login_in_user'
post 'login/login_in_some_other_way' => 'login#login_in_some_other_way'
# ...
end
Some of your other routes seem a bit off to me as well. If you haven't already, I'd highly recommend reading this rails guide: http://guides.rubyonrails.org/routing.html.
EDIT:
One thing I should explain just in case is that rails won't allow access to your controller's actions automatically. You always need to have an entry in the routes file for every url the user would need to access. In your case, you have a simple catch-all rule at the bottom that looks like this:
# Install the default route as the lowest priority.
match ':controller/:action/:id'
This is not recommended anymore, since it gives needless access to too many actions and no restrictions on the access method (GET, POST, etc.). Even so, if you want to install a catch-all route to your admin interface, you could do the same in your :admin namespace:
namespace :admin do
match ':controller/:action/:id'
end
This should solve your problem in this case, but again, it's generally not a good idea. I'm under the impression that you're dealing with legacy code, so it may be a reasonable temporary fix, but I'd still create all the necessary routes by hand first and then think about how to rewrite the controllers to work sensibly with resources. As I noted above, for your problem, this should do the trick:
namespace :admin do
post 'login/login_in_user' => 'login#login_in_user'
end

Related

creating custom routes in rails

I am creating a custom route like:
namespace :admin do
root 'users#index'
resources :users do
get 'admin_login' => 'users#admin_login'
end
end
But when I see with rake routes:
admin_user_admin_login GET /admin/users/:user_id/admin_login(.:format) admin/users#admin_login
Why :user_id is added here?
I just want it without :user_id.
Because you are creating a custom route within the users resource. Rails is doing exactly what you are telling it to do. You would like to show the "admin_login" route for a specified user (that's what you're currently telling rails to do).
Move the:
get 'admin_login' => 'users#admin_login'
Line of code outside of the resources block and you'll be able to create your custom route.
You need to specify an on option to tell Rails that it works on a collection and not a member resource. According to the official Rails routing guide
You can leave out the :on option, this will create the same member
route except that the resource id value will be available in
params[:photo_id] instead of params[:id].
You can also remove the => 'users#admin_login' part as that is the default behavior.
So the solution to your problem is to add on: :collection or place it inside a block like
namespace :admin do
root 'users#index'
resources :users do
collection do
get 'admin_login'
end
end
end

Ruby on Rails : add a new route

I'm new with RoR so this is a newbie question:
if I have a controller users_controller.rb and I add a method foo, shouldn't it create this route?
http://www.localhost:3000/users/foo
because when I did that, I got this error:
Couldn't find User with id=foo
I of course added a view foo.html.erb
EDIT:
I added to routes.rb this code but I get the same error:
resources :users do
get "signup"
end
This doesn't work automatically in rails 3. You'll need to add
resource :users do
get "foo"
end
to your routes.rb
You'll definitely want to have a look at http://guides.rubyonrails.org/routing.html, it explains routing pretty well.
Rails is directing you to the show controller and thinks that you're providing foo as :id param to the show action.
You need to set a route that will be dispatched prior to being matched as /users/:id in users#show
You can accomplish this by modifying config/routes.rb by adding the following to replace your existing resource describing :users
resource :users do
get "foo"
end
Just to add to the other answers, in earlier versions of Rails there used to be a default route
match ':controller(/:action(/:id))(.:format)'
which gave the behaviour you describe where a request of the form controller/action would call the given method on the given controller. This line is still in routes.rb but is commented out by default. You can uncomment it to enable this behaviour but the comment above it explains why this is not recommended:
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
At the schema ':controller/:action(.:format)', you can also easily do the following
resources :users do
get "foo", on: :collection
end
or
resources :users do
collection do
get 'foo'
end
end
http://guides.rubyonrails.org/routing.html#adding-collection-routes

My routes has resources :home, but rspec is saying routes not defined?

My homecontroller has:
def about()
end
And I have a rspec test that does GET 'about' and it fails saying that there is no route that matches.
doesn't this map all actions in the controller:
resources :home
or do I have to explicitly state each action in the home controller?
resources :home sets up the default RESTful routes - index, show, new, create, edit, update, and destroy. Any additional routes have to be specified. It looks like you're adding a simple collection route, so you'd specify it like this:
resources :home
collection do
get 'about'
end
end
This will give your the route '/home/about'. I assume this is Rails 3. If you're in Rails 2.x, do it like so:
map.resources :home, :collection => {:about => :get}
And from the command line, you can always see what routes you have available with this command:
rake routes
I hope this helps!
EDIT: If you want a default route, you can add this:
match ':controller(/:action(/:id))'
This is a default route that will match any generic requests.
FULL ARTICLE: Routing in Rails 3 is its own beast. There have been a lot of questions about it lately, so I've created a very detailed article with code samples to help others:
Routing in Ruby on Rails 3
I created a companion Rails 3 app that can be downloaded to play around with, as well:
https://github.com/kconrails/rails3_routing
If you have any questions, please hit up my site and ask. Thanks!
resources will give you the 7 CRUD methods for a controller, if you want additional actions, you need to do something like the following:
resources :homes do
collection do
match "about" => "homes#about", :as => "about"
end
end
Then you'll also have an additional about_homes_path/url helper available.

How do you check the URL Helpers for a Model Resource in Rails?

I'm currently following the Shovell tutorial in the Simply Rails 2 book. On page 168, it mentions URL Helpers for the Story Resource:
stories_path /stories
new_story_path /stories/new
story_path(#story) /stories/1
edit_story_path(#story) /stories/1/edit
The above is then used in the controller:
def create
#story = Story.new(params[:story])
#story.save
redirect_to stories_path
end
My routes.rb:
ActionController::Routing::Routes.draw do |map|
map.resources :stories
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
It looks like stories_path is the url name to /stories. Is that explicitly defined somewhere within my app, I can't seem to grep for that keyword. If not, is there a way that I can check the mapping above from the Rails console or somewhere else? In Django, url names are usually explicitly defined in urls.py, I just can't figure out how the above is being generated. Any documentation and pointers will help.
To get a list of the mapped routes:
rake routes
What map.resources :stories is doing is mapping your RESTful actions (index, show, edit etc.) from the stories_controller.rb to named routes that you can then use for simplicity.
routes.rb includes helpful tips on defining custom routes and it may be worth spending a little bit of time looking at resources in the API to get a better understanding:
http://api.rubyonrails.org/classes/ActionController/Resources.html#M000522
I think checking out the Rails Guides on Routing will help you a lot to understand what's going on
In short, by using the
map.resources :stories
the Router will automatically generate some useful (and RESTful) routes. Their path will take the model name (remember in Rails there is the Convention over Configuration motto), and, by default, will generate routes for all the REST actions.
This routes are available through your controller, views, etc.
If you want to check out which routes are generated from your mappings, you can use the "rake routes" command.
Now, given that, you can also write explicit URLs on your routes.rb file for actions or events that don't quite comply with the REST paradigm.
For that, you can use
map.connect "/some_kind_of_address", :controller => :pages, :action => "something_else"
Or
map.home "/home", :controller => :pages, :action => "home"
The last one will gave you both home_path and home_url routes you can use in your code.

RoR resources: No action responded to 1

I'm using the following code to map my resources for my products controller:
map.namespace :admin do |admin|
admin.resources :products
end
In my view I'm using
link_to 'Edit', edit_admin_product_path(product)
which results in the URL /admin/products/1/edit
when I'm clicking on the link I'm getting
Unknown action
No action responded to 1
So I guess it doesn't properly map it to the edit action.
I have no idea what to do.
The is route valid otherwise it'd be blowing up when you try to create your link. Does your product controller have an edit action?
Usually when I put a namespace in my routes it follows through to my controller and views. For example the full path would be
/controllers/admin/products_controller.rb
/views/admin/products/edit.html.erb
You'd also put a namespace in your controller too:
class Admin::ProductsController < ApplicationController
Do you have these lines in your routes file?
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
If so, make sure they are below your resource route lines. Those lines should always be near the bottom of your routes.rb because they are so generic. The more specific the route, the higher up it should be.

Resources