Rails Tutorial 3.2 Глава 8 ошибка: NoMethodError в SessionsController#create

Я просматриваю учебник по рельсам, и моя страница входа выдает исключение после упражнения 8.1.5, когда я нажимаю кнопку входа без ввода адреса электронной почты или пароля: http://ruby.railstutorial.org/chapters/sign-in-sign-out#sec-rendering_with_a_flash_message

Ошибка:

NoMethodError in SessionsController#create
undefined method `[]' for nil:NilClass
app/controllers/sessions_controller.rb:7:in `create'

SessionsController точно соответствует окончательному коду метода Create.

class SessionsController < ApplicationController

  def new
  end

  def create
    user = User.find_by_email(params[:session][:email].downcase) #line 7
    if user && User.authenticate(params[:session][:password])
      #will fill this in later
    else
      flash.now[:error] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
  end
end

Я изменил метку кнопки на «Войти» вместо «Войти», так как это слишком запутанно с «Зарегистрироваться», но я не думал, что это создаст проблему. сессии\new.html.erb

<% provide(:title, "Log in") %>
<h1>Log in</h1>
<div class="row">
  <div class="span6 offset3">
    <%= form_for(:sesssion, url: sessions_path) do |f| %>
        <%= f.label :email %>
        <%= f.text_field :email %>

        <%= f.label :password %>
        <%= f.password_field :password %>

        <%= f.submit "Log in", class: "btn btn-large btn-primary" %>

    <% end %>
    <p>New user? <%= link_to "Sign up now!", signup_path %></p>
  </div>
</div>

Этот пост намекает, что мне нужен метод в моей пользовательской модели, но добавление этого не помогло: NoMethodError in SessionsController#create

Я попытался добавить это в user.rb, но это не помогло from-console">результаты выполнения find_by_email в функции отличаются от консольных:

def self.authenticate(email, submitted_password) 
    user = find_by_email(email)
    return user.nil? ? nil : user
end

Благодарим за любую идею!


person John Kucera    schedule 11.03.2013    source источник
comment
Привет, у вас есть метод User.authenticate(params[:session][:password])? В вашем файле User.rb.   -  person Hass    schedule 11.03.2013
comment
Нет, я пытался добавить это, но это не помогло: def self.authenticate(email, submit_password) user = find_by_email(email) return user.nil? ? nil : конец пользователя   -  person John Kucera    schedule 11.03.2013


Ответы (5)


Я посмотрел на пример из книги и ваш код, и я заметил эту строку

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

ваш User.authenticate должен быть в нижнем регистре до user.authenticate. Вернитесь к исходному коду.

person Hass    schedule 11.03.2013
comment
Спасибо - не удалось добавить это в user.rb :( Я попытался изменить ваш выше, чтобы использовать адрес электронной почты вместо имени, и все равно не повезло. Мой запрос показывает параметр сеанса с включенным адресом электронной почты и pw, но если у меня есть params[:session ][:email], я всегда получаю сообщение об ошибке. Например, это создает ошибку в той же строке: @email=params[:session][:email] - person John Kucera; 11.03.2013
comment
Подождите, позвольте мне взглянуть на пример и вернуться к вам. - person Hass; 11.03.2013
comment
Я исправил ответ. Вы должны удалить метод, который я упомянул в первом ответе. Надеюсь, теперь это работает! - person Hass; 11.03.2013
comment
Я очень ценю ваше время - нижний регистр u не работал у меня ни с какой комбо (пользователь в методе аутентификации users.rb, пользователь в session_controller, пользователь, пользователи или пользователь, пользователь) - person John Kucera; 11.03.2013
comment
кстати, также прокомментировал новый метод user.authenticate в users.rb и попробовал прописные и строчные буквы. Кажется, ошибка в строке назначения параметра по сравнению с методом аутентификации, но трассировка стека показывает, что параметры должны быть там и должны быть в порядке. - person John Kucera; 11.03.2013
comment
Можете ли вы попробовать это определение создать пользователя = User.find_by_email(params[:session][:email].downcase) если пользователь #заполнит это позже else flash.now[:error] = 'Неверная комбинация электронной почты/пароля' render ' новый' конец конец - person Hass; 11.03.2013
comment
Резюме ниже — session_controller.rb и users.rb в порядке, я что-то сломал в route.rb, header.html.erb или new.html.erb. В итоге я отказался от своих route.rb, header.html.erb и new.html.erb для настройки сеансов, чтобы использовать «Войти и войти» вместо «Войти и войти», что помогло мне решить проблему. Я по-прежнему полон решимости выяснить точное изменение, которое нарушило вышеизложенное, и обновлю эту ветку после решения. Еще раз спасибо за все время! - person John Kucera; 11.03.2013
comment
Да пожалуйста! Я не уверен, знаете ли вы это, но в своей консоли вы можете ввести rake route, чтобы получить все доступные маршруты и на какие функции они указывают, и какие параметры вы можете получить в них. Пожалуйста. Просто жаль, что я не мог помочь лучше. - person Hass; 11.03.2013
comment
Вы были правы - нижний регистр u сделал свое дело, но все еще не уверен, почему мне потребовалась замена других моих файлов, чтобы заставить его работать. Я просмотрел и проверил все мои другие файлы и воссоздал свои настройки. Спасибо за помощь! - person John Kucera; 11.03.2013
comment
Это действительно здорово. Иногда, в отличие от PHP, rails не принимает сдачу сразу, хотя должна. Иногда перезапуск сервера творит чудеса! Добро пожаловать снова :) - person Hass; 11.03.2013

У меня только что была такая же проблема, и я обнаружил, что на самом деле мне нужно [:sessions] с буквой s в конце!

Итак, строка читается

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

Надеюсь, это поможет кому-то в будущем!

person daraz51    schedule 08.04.2013
comment
Я тоже ищу решение... Когда я добавляю s, я получаю недопустимую хеш-ошибку. - person Linus; 16.04.2013
comment
Когда я использую сеанс и данные для входа верны, он работает! НО, когда информация для входа неверна, я получаю неверную хеш-ошибку. - person Linus; 16.04.2013

У меня была та же проблема после выполнения упражнения 1 в главе 8, где я заменил использование form_for на form_tag. В результате атрибуты имени в сгенерированных полях формы ввода изменились с name="session[email]" и name="session[password]" на name="email" и name="password". Впоследствии мне нужно было получить доступ к параметрам, используя params[:email] и params[:password] вместо params[:session][:email] и params[:session][:password].

Мой новый контроллер Sessions выглядит так:

class SessionsController < ApplicationController

  def new
  end

  def create
    user = User.find_by_email(params[:email].downcase)
    if user && user.authenticate(params[:password])
      sign_in user
      redirect_to user
    else
      flash.now[:error] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    sign_out
    redirect_to root_url
  end
end

Это решило проблему для меня. Надеюсь, это полезно для кого-то еще.

person Mark Steiner    schedule 08.10.2013

В этом разделе руководства, глава 8, все экземпляры [:session] должны быть [:sessions]. Надеюсь, это поможет.

class SessionsController < ApplicationController
  .
  .
  .
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      sign_in user
      redirect_to user
    else
      flash.now[:error] = 'Invalid email/password combination'
      render 'new'
    end
  end
  .
  .
  .
end
person Pat SB    schedule 24.11.2013

Не могли бы вы подтвердить правильность написания слова «сессия» в app/view/session/new.html.erb?

Я вижу, вы написали:

form_for(:session, url: session_path) do |f|

Но в app/controllers/sessions_controller.rb вы написали:

user = User.find_by_email(params[:session][:email].downcase) #строка 7

Они должны быть одинаковыми.

person ahnniu    schedule 03.08.2014