Pergunta

I try to create a Sign_in-formular (link to tutorial), but I get the following error-code:

Started GET "/user/sign_in" for 127.0.0.1 at 2014-04-07 17:50:54 +0200
ActiveRecord::SchemaMigration Load (1.0ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by UserController#sign_in as HTML
Rendered user/sign_in.html.erb within layouts/application (19.0ms)
Completed 500 Internal Server Error in 92ms

ActionView::Template::Error (First argument in form cannot contain nil or be empty):
1: Sign In
2: <%= form_for @user, :as => :user, :url => sign_in_path(@user) do |f| %>
3: <%= f.label 'username or email:' %>
4: <%= f.text_field :username %>
app/views/user/sign_in.html.erb:2:in `_app_views_user_sign_in_html_erb___114454536_30263052'

Furthermore I add everything (I think that's all you need to understand), which depents on the error-code.
If you need more Information, just tell me.
Please also tell me, if I add TOO much information.
I#ll edit the post afterwards.

Model: (user.rb)

class User < ActiveRecord::Base
  attr_accessible :email, :username, :password, :password_confirmation
  attr_accessor :password
  before_save :encrypt_password

  validates_confirmation_of :password
  validates_presence_of :password, :on => :create
  validates_presence_of :email, :on => :create
  validates_presence_of :username, :on => :create
  validates_uniqueness_of :email
  validates_uniqueness_of :username

  def self.authenticate_by_email(email, password)
    user = find_by_email(email)
    if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
      user
    else
      nil
    end
  end

  def self.authenticate_by_username(username, password)
    user = find_by_username(username)
    if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
      user
    else
      nil
    end
  end

  def encrypt_password
    if password.present?
      self.password_salt = BCrypt::Engine.generate_salt
      self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
    end
  end
end

Controller: (user_controller.rb)

class UserController < ApplicationController
  def sign_in
    @user = User.new
  end

  def login
    username_or_email = params[:user][:username]
    password = params[:user][:password]

    if username_or_email.rindex('@')
      email = username_or_email
      user = User.authenticate_by_email(email, password)
    else
      username = username_or_email
      user = User.authenticate_by_username(username, password)
    end

    if user
      flash[:notice] = 'Welcome'
      redirect_to :root
    else
      flash[:error] = 'Unknown user. Please check your username and password.'
      render :action => "sign_in"
    end
  end

  def change_pw
  end

  def forgot_pw
  end

  def new
  end

  def sent_pw
  end

  def sign_in
  end

  def signed_out
  end
end

View: (sign_in.html.erb)

<p>Sign In</p>
<%= form_for @user, :as => :user, :url => sign_in_path(@user) do |f| %>
    <p>
      <%= f.label 'username or email:' %><br />
      <%= f.text_field :username %>
    </p>
    <p>
      <%= f.label 'password:' %><br />
      <%= f.password_field :password %>
    </p>
    <p>
      <%= f.submit 'Sign In' %>&nbsp;&nbsp;&nbsp;
      <%= f.submit 'Clear Form', :type => 'reset' %>
    </p>
<% end %>

Routes (routes.rb)

Calendar::Application.routes.draw do
  root "welcome#index"

  get "user/change_pw"
  get "user/forgot_pw"
  get "user/new"
  get "user/sent_pw"
  get "user/sign_in"
  get "user/signed_out"
  get "welcome/index"

  post "sign_in" => "user#login" #ein HTTP post auf der Seite sign_in führt die Methode login im user controller aus
end
Foi útil?

Solução

You have defined sign_in method twice in UserController. Remove the second definition(empty method) of sign_in from the bottom of the UserController.

As you can see, you have redefined the method sign_in, so Ruby would pick the latest method definition for evaluation in which you don't have @user set. Hence, the error.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top