form_for is always posting to "new" despite url: parameter being set

Hi all,

I’m trying to code log in/out and session logic into my first rails app. The session#new resource has no problem showing me the log in page and form, but every time I click submit it posts to sessionscontroller#new (again) instead of create, despite the fact that I’ve given it the create path in the url: parameter:


root ‘static_pages#homepage’

match ‘/about’, to: ‘static_pages#about’, via: ‘get’

match ‘/signin’, to: ‘sessions#new’, via: ‘get’

match ‘/signout’, to: ‘sessions#destroy’, via: ‘delete’

match ‘/signup’, to: ‘static_pages#homepage’, via: ‘get’

resources :users

resources :dashboards

resources :sessions, only: [:new, :create, :destroy]

rake routes:

sessions POST /sessions(.:format) sessions#create

new_session GET /sessions/new(.:format) sessions#new

session DELETE /sessions/:id(.:format) sessions#destroy

the app/views/sessions/new.html.rb code



21 Sign In with your email address and password

22 <%= form_for(:session, url: sessions_path) do |f| %>

23 <%= f.label :email_address %>

24 <%= f.text_field :email_address, :placeholder => “you@location. domain” %>


26 <%= f.label :password %>

27 <%= f.password_field :password %>


29 <%= f.submit “Sign in”, :class => “btn btn-large btn-success” %>

30 <%end%>



Don’t have an account? <%= link_to “Sign up!”, signup_path %>



class SessionsController < ApplicationController

def new


def create

user = User.where(:email_address => params[:session][:email_address].downcase). first()

if user && user.authenticate(params[:session][:password])

sign_in user

redirect_to dashboard_path(user)

else[:error] = ‘Invalid email/password combination’

render ‘new’



def destroy



What happens in the server logs when I click “sign in”

Started GET “/signin?utf8=%E2%9C%93&authenticity_token=9LMTkTw1VDYWm%2F0UMzRdxzTm29Bu91g76stVAYu%2BROU%3D&[FILTERED]&commit=Sign+in” for at 2013-09-26 16:53:27 +0000

Processing by SessionsController#new as HTML

Parameters: {“utf8”=>“✓”, “authenticity_token”=>“9LMTkTw1VDYWm/0UMzRdxzTm29Bu91g76stVAYu+ROU=”, “session”=>{“email_address”=>“”, “password”=>“[FILTERED]”}, “commit”=>“Sign in”}

Rendered sessions/new.html.erb within layouts/application (3.4ms)

Completed 200 OK in 15ms (Views: 14.5ms)

I have stared at this for hours, I have no idea what I’m missing. Any help is appreciated.



It is not legal html to have nested forms.


And the point of that is that the browser will take apart that illegal page and make a valid form out of it, ignoring the nested child. Make this into a test page in your text editor, and view it in a browser.

    <!DOCTYPE html>     <html>     <head>       <meta charset="utf-8" />       <title>untitled</title>     </head>     <body>     <form action="foo" method="get" accept-charset="utf-8">       <form action="bar" method="get" accept-charset="utf-8">         <p><input type="text" value="baz"/></p>       </form>       <p><input type="text" value="boo"/></p>     </form>     </body>     </html>

If you view source, and actually look at the source code, you'll see what I typed here. If you view the DOM (what the browser made out of it) you will see this instead:

    <!DOCTYPE html>     <html><head>       <meta charset="utf-8">       <title>untitled</title>     </head>     <body>     <form action="foo" method="get" accept-charset="utf-8">                <p><input type="text" value="baz"></p>       </form>       <p><input type="text" value="boo"></p>      </body></html>

See how the outer form is all that is left, and the inner form's contents have been shifted outside of the outer form entirely? That's just what Safari does -- other browsers may put the elements in a slightly different order -- but you can't control this. The only way around it is to code a valid HTML page. Then, if the browsers mess it up, that's on them, not you.