Search code examples
ruby-on-railsnomethoderrorrails-flash

NoMethodError: undefined method `[]' in rails 3


Here is my SessionsController

class SessionsController < ApplicationController

def new
end

def create
    user = User.find_by_email(params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
        # Sign the user in and redirect to the user's show page.
        sign_in user
        redirect_to user
    else
        flash.now[:error] = 'Invalid email/password combination' # Not quite right!
        render 'new'
    end
end


def destroy
end

end

Here is the routes.rb

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

also the respective routes for new and destroy views.

Here is the new.html.erb

<% provide(:title , "Sign in")%>
<div id="signin_page" class="hero-unit container-fluid">
<h1>Sign In</h1>
<div class="row span6">
<%= simple_form_for :sessions, url: '/sessions', html: {:class=> 'form-horizontal'} do |f| %>
<%= f.input :email, label: "Email", placeholder: "Enter email",required: true%>
<%= f.input :password, label: "Password", placeholder: "Enter Password", required: true%>
<p id="signin_button"><%= f.button :submit, "Sign in", class: "btn btn-large btn-primary span2" %> 
    New user? <%=link_to "Sign up now!", '/signup'%></p>

<% end %>
</div>

The error is like. enter image description here

what I'm trying to implement is that, the sign in success/failure shouldrender the respective views with the flash messages. Where am I going wrong. I'm newbie to ROR


Solution

  • You have to use sessions instead of session i.e. Use

    params[:sessions][:email]
    

    instead of

    params[:session][:email]
    

    As your form says sessions i.e. simple_form_for :sessions.

    But in controller you are accessing params[:sessions] which is nil and then calling [:email] on it hence it is giving error

    undefined method '[]' for nil:NilClass
    

    hence change

    user = User.find_by_email(params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
    

    To

    user = User.find_by_email(params[:sessions][:email].downcase)
    if user && user.authenticate(params[:sessions][:password])
    

    and then it should work