RoR resources: No action responded to 1 - ruby-on-rails

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.

Related

Getting 'Unknown action in controller'

I'm getting this error :
"The action 'create' could not be found for ObjectController"
I know it should be obvious but I'm missing something, that's my controller :
class ObjectController < ApplicationController
def index
end
def create
end
end
And that is my routes :
Rails.application.routes.draw do
get 'object/index'
get 'object/create'
match ':controller(/:action(/:id))', :via => :get
resources :objets
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
root 'object#index'
You probably want to scrap those routes and try something simpler like
resources :objects, only: [:get, :create, :show]
Then use
$ rake routes
To make sure your routes are as the should be. You will want a POST route to /objects to create a new object etc..
Ok that one was dumb, actually I had two directories and I wasn't modifying the right one, sorry about that...
Your routes could be greatly improved:
#config/routes.rb
Rails.application.routes.draw do
root 'objects#index'
resources :objects
--
Next, the "standard" way to achieve what you're looking for is to use the new action; IE not the "create" action. If you wanted to use the create path name (instead of new), you'll be able to define it in the path_names argument:
#config/routes
resources :objects, path_names: { new: "create", create: "create" } #-> url.com/objects/create
To understand why you should be using new instead of create, you should look up resourceful routing, and how it pertains to object orientated programming.
Finally, your controller should be named in the plural:
#app/controllers/objects_controller.rb
class ObjectsController < ApplicationController
...
end
Whilst you can call it whatever you like, Rails defaults to plural controller names, singular model names.

Rails not throwing routing error when invalid url is entered

In my rails 2.3.X application there is User resource which is nested under many other resources and is not exposed directly.
map.resources :resource1 do |r|
r.resources :users
end
map.resources :resource2 do |r|
r.resources :users
end
# map.resources :users is not mentioned any where.
When I hit "/user" or "/users-any-invalid-url" it shows routing error but when I hit "/users" it takes me to index action of users_controller which is not desired. I want to get the same routing error.
How to get that? Thanks In advance.
Since this is a rails 2 app, there is a default route found at the bottom of route.rb
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
So as long as your have a users controller, it will go to that controller. The solution is to simply remove those 2 lines. Removing those 2 lines also protect you from various unwanted requests.

Rails routing error help No route matches

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

How to change URL in Rails

I have a resource called Book, then I have domains like:
domain.com/books/272
But I want to change it to
domain.com/stories/272
Only for the URL, don't need to change controller, classes etc.
In the routes I have
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
map.root :controller => 'static'
How can I do it? Thanks
In rails 3, I believe you would do the following:
resources :books, :path => 'stories'
Depends really on what you have already.
Use this code to your routes file: (in the case of the original URL of books replaced by stories)
#resource routes
map.resources :books, :as => :stories
#named routes
map.books 'stories/:id'
Without defining routes the only option I can think of - which seems terribly wrong - is to add a new controller which inherits from your books controller. You'd need to go through your application and change the controller name used to generate paths or URLs as seen in the following example:
class BooksController < ApplicationController
class StoriesController < BooksController
Personally, I would recommend you take the time to define your routes but I guess this depends on how large an application you're working with.
This guide will help you understand routing in RoR: http://guides.rubyonrails.org/routing.html
Its called named routes and is done in your config/routes.rb
In your routes file:
map.stories 'stories/:id', :controller => 'books', :action => 'show'
Then in your view you can access this route with:
<%= link_to book.name, stories_path(book) %>
Make sure you change book.name to whatever name you want. also make sure you passing book as a local variable to the routes path.
You can also change the :id to be more SEO friendly with to_param in the respective model.
In your model:
def to_param
"#{id}-#{name.gsub(/\s/, '_').gsub(/[^\w-]/, '').downcase}"
end
Also make sure you replace name with an attribute that the book model actually has.

Ruby On Rails Routes

I can't figure out how to get the following routes. Here's an extract from my routes.rb file:
map.resources :treatments
map.root :controller => "home"
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
map.connect ':action', :controller => 'home' # replaces the need to manually map pure actions to a default controller
map.resources :bookings
map.resource :dashboard
map.resource :home
Now I do realise that the ordering matters, but I can't seem to get them to work correctly.
What I want is so http://localhost:3000/bookings/new actually takes you to an action http://localhost:3000/bookings/signmeup if you're either not signed in, or haven't got a login. The problem is that if I change my routes around, when I attempt to create a new booking after I have logged in, then it doesn't POST the form submission and just takes me back to the view page. This is definitely because of the routes as if I rearrange map.resources :bookings to be before all of them, then it works.
Any ideas?
As a rule of thumb, you want your resource routes to come before the generic :controller/:action/:id routes (in fact, I go so far as to delete the generic routes entirely), since routes that are defined first take precedence over the ones that are assigned later.
As for redirecting to /bookings/signmeup if the user is not logged in, you should handle that with a before_filter:
class BookingsController < ApplicationController
before_filter :check_login
# ...
protected
# This is a GENERIC example; change to fit your authentication method
def check_login
unless user_is_logged_in
redirect_to ...
end
end
end

Resources