Rails route question - ruby-on-rails

I have a login form (/user).
And methods:
-authenticate
-logout
And one view index.html.erb, it contains the login form, authenticate is work fine, but I think I have problems with routing.
Can you give me a sample route?
My router looks like:
map.logout 'logout', :controller => 'sessions', :action => 'destroy'
map.login 'login', :controller => 'sessions', :action => 'new'
In sessions control have destroy method, but when I type /logout it's say: Missing template session/destroy.erb in view path app/view

A sample route in Rails 3
match '/user(/index)' => 'users#index'
It would be helpful if you could clarify the issue you're having (and post relevant code).

All routing system is explain on guides :
http://guides.rubyonrails.org
This one in particular : http://guides.rubyonrails.org/routing.html

Related

Why to add a connection in routes file when using link_to in rails 2

I was trying to accomplish the following:
<%= link_to "Log out", { :controller
=> 'users', :action => 'logout' }, :class => 'menulink2' %>
But it didn't work, it always redirected me to a show view. I had to had the following to my routes.rb:
map.connect 'users/logout',
:controller => 'users', :action =>
'logout'
Why didn't rails recognize the action I was passing ('logout') ?
That logic has to be specified somewhere. There's got to be some mapping from the hash {:controller => 'users', :action => 'logout'} to a url, and the place that's done in rails is the routes.rb file. In older versions of rails many routes.rb came with a default at the end:
map.connect ':controller(/:action/(:id(.:format)))'
Which would make it so that most any :controller, :action hash could be specified and then routed to host.url/:controller/:action.
With the more modern versions resource-based routes are heavily favored, and controllers which don't follow rails' REST conventions (i.e. having only :index,:show,:create,:new,:edit,:update,:destroy methods) generally have to have their routes explicitly specified in some way.
(Either with map.resources :users, :collection => {:get => :logout} or with map.connect( 'some_url', :controller => 'users', :action => 'logout'}))
I'm guessing, but the reason they did that is probably that the actions of a controller are really just its public methods.
It's frequently nice to have public methods in your controllers that aren't url-end-points for testing purposes.
For instance, you could have before_filters as public methods that you might want to test without having to use #controller.send(:your_before_filter_method) in your test code.
So they whitelist the resource actions, and make the others unreachable by default. Let me look through the rails changelog and see if I'm right.

Is it possible to create a route like '~:id' in Rails 2.x?

I have been using the following route successfully in my Rails 2.x application:
map.user ':id', :controller => 'users', :action => 'show'
This, as my lowest route, properly catches things like /tsmango and renders Users#show.
I'm now trying to add a second, similar route like:
map.post '~:id', :controller => 'posts', :action => 'show'
Because neither my users or my posts are allowed to contain ~ and because this route will appear above my map.user route, I assumed this would properly catch any call starting with /~ and render my Posts#show action. Unfortunately, I'm having trouble getting this one to work.
What's interesting is that this similar route works perfectly:
map.post ':id~', :controller => 'posts', :action => 'show'
Although, I'm certainly willing to go with ':id~' since it has the same result, at this point I'm really just frustrated and curious as to how you would build a route that matches '~:id'.
It's worth mentioning that I do not want to modify my to_param method or my actual user and post slugs to include the prepended ~. I just want that in a route to indicate which action should handle it. Unless I'm mistaken, this rules out the use of something like:
:requirements => {:id => /\~[a-zA-Z0-9]/}
Thanks, in advance, for any help you can provide!
Update: I'm aware of route priority and stated above that I am placing the '~:id' route above the ':id' route. I receive the following error while trying to generate the url like post_path(#post):
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.to_sym
Routes are prioritized depending of the order in which they're declared.
When you define first the :id route, the second one is never executed.
In order for this to work, you just have to first define the ~:id route and then the :id one.
map.post '~:id', :controller => 'posts', :action => 'show'
map.post ':id', :controller => 'users', :action => 'show'

How do I fix this routing error in Ruby on Rails?

I've put this line in my routes.db file:
map.mything '/mything', :controller => 'mything', :action => 'list'
But I get this error when I go to http://localhost:3000/mything, I get this error:
Unknown action
No action responded to index. Actions: list
Why is it trying to use index instead of list? I thought that by setting
:action => 'list'
it would use the list action? Thanks for reading.
You have to put named routes above the default routes.
I put named routes like these at the top of routes.rb so they always get evaluated first.
ActionController::Routing::Routes.draw do |map|
map.about 'about', :controller => 'home', :action => 'about'
map.contact 'contact', :controller => 'home', :action => 'contact'
# MORE CONFIG
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
Agreeing with Jim Schubert, put the named routes above the default routes.
Another likely problem is that you have something like:
map.resources :mything
which is setting an index action on the controller as a result of you scaffolding a model
Sorry for asking a potentially obvious question, but have you tried restarting the app? Certain routes will not register until you restart the application (RESTful resources never need an application restart, but others often do).

redirect_to and :controller, :actions getting mixed up in Rails

In a Rails controller I'm calling this:
redirect_to :controller => "user", :action => "login"
My user_controller.rb defines the following method:
class UserController < ApplicationController
def login
###
end
When I call my redirect_to method I get this error in my browser: No action responded to show. Checking the server logs I see this line:
Processing UserController#show (for 127.0.0.1 at 2009-12-19 12:11:53) [GET]
Parameters: {"action"=>"show", "id"=>"login", "controller"=>"user"}
Finally, I've got this line in my routes.rb
map.resources :user
Any idea what I'm doing wrong?
The hack-y answer is to change the following line in your routes.rb
map.resources :user
to
map.resources :user, :collection => { :login => :get }
But that's bad for a variety of reasons -- mainly because it breaks the RESTful paradigm. Instead, you should use a SessionController and use sessions/new to login. You can alias it to /login by the following line in routes.rb
map.login 'login', :controller=>"sessions", :action=>"new"
Tried
redirect_to :url => {:action => 'login', :controller => 'user'}
Or you might have to remove the routing or write your own. The routing maps POST to create, PUT to update etc.
You need to add the login action in your routes.rb. Refer to this excellent guide.
What I ended up doing was creating a new login_controller to handle logins.
Here's the relavent bit from my routes.rb file:
map.login '/login', :controller => 'login', :action => 'login'
Thanks for your help...

Organisation of routes in Rails -- restful_authentication, session and /login

I am struggling with the route setup for a Rails application. I have installed restful_authentication and mostly followed the instructions. I have set up the routes this way:
map.login '/login', :controller => 'sessions', :action => 'new'
map.logout '/logout', :controller => 'sessions', :action => 'destroy'
map.resource :session
If you're not logged in, you're redirected to http://localhost:3000/session/new.
It makes some kind of sense, as the code in lib/authenticated_system.rb says redirect_to new_session_path.
But I thought the routes mapping was supposed to work both ways (code to URL and URL to code). Can someone explain? Thanks
map.resource :session creates a few named resources for you including new_session_path (see ActionController::Resources).
map.login and map.logout are just helper routes to make your code easier to understand. map.login (which generates login_path) points to the same controller/action combo as new_session_path does, it's just easier to remember at a glance what it does.

Resources