Umm... pretty much lost

I believe I should have done everything correct here. I have a user_controller. I am trying to add a login method, so I add:

  # GET /users/login   def login     if request.post? and params[:user]       @user = User.new(params[:user])       user = User.find_by_username_and_password(@user.username,@user.password)       if user         session[:user_id] = user.id         flash[:notice] = "Welcome online, #{@user}"         #redirect_to :action => "show"         redirect_to :action => "index"       else         #remove Password from the view         @user.password = nil         flash[:notice] = "Invalid username/password combination."       end

    end

  end

Then I create in /views/users/ the file called login.rhtml.

But for some reason, whenever I go to /public/users/login, Rails thinks login is supposed to be a userid, and so it takes me to my show.rhtml and show action. The login.rhtml page comes up when I use / public/users/login/[anything], though... so why does it not recognize it as a proper action? It insteads thinks show is the action by default when a userid is present. Any ideas?

I'm guessing you're using RESTful routes, is that true?

It appears that way... seems to have been the default that happened after scaffolding. So, I added this line to my index.rhtm:

<%= link_to 'Login', login_user_path %>

And got a no method error of some sort, so I tried this:

<%= link_to 'Login', :controller => "users", :action => "login" %>

and that makes a link that doesn't work. I checked routes.rb, and there is nothing in there about users other than the standard "map.resources :users".

Use 'rake routes' to get information on the route mappings. If you've got a resource called 'users' defined in routes.rb, then 'rake routes' will show you something like this:

user GET /users/:id {:action=>"show", :controller=>"users"}

This means that a 'GET' request to a URL of the form /users/login will treat the '/login' part as a user id and will call the 'show' action of the 'users' controller. Which is exactly the behavior you're getting. If you want to define a 'login' action for users that works on the whole collection, then you need to add something like this to routes.rb:

map.resources :users, :collection => {:login => :get}

But then when I submit the form it thinks I'm supposed to be pointed to the create action, instead of the :login action... so I tried to add:

map.resources :users, :collection => {:login => :post}

But that didn't work. How do I do that part?

I probably have to change this part somehow:

<% form_for(:user, :url => users_path) do |f| %>

<% form_for(:user, :url => users_path) do |f| %>

or, simply <% form_for @user do |f| %> (as long as @user == User.new)

will point to the create action

You need to point it to the login path:

<% form_for :user, :url => login_user_path, :method => :get do |f| %>

With this mapped resource:

map.resources :users, :collection => { :login => :get }