form_for - 表单中的第一个参数不能包含nil或为空

时间:2014-04-09 15:27:17

标签: ruby-on-rails ruby ruby-on-rails-4

如果我输入用户的用户名和密码,一切正常,但如果我没有输入或只是用户名,则会出现以下错误:

First argument in form cannot contain nil or be empty in <%= form_for @user, :as => :user, :url => user_sign_in_path(@user), :html => {:class => 'navbar-form', :role => 'login'} do |user_form_builder|%>

app/views/user/sign_in.html.erb:10:in '_app_views_user_sign_in_html_erb__420697496_32907636' app/controllers/user_controller.rb:23:in 'login'

我认为你需要控制器,路线和视图:

查看:

<%= form_for @user, :as => :user, :url => user_sign_in_path(@user), :html => {:class => 'navbar-form', :role => 'login'} do |user_form_builder|%>
      <div class="form-group text-xs">
        <%= user_form_builder.text_field :username, :class => 'form-control input-xs', :placeholder => 'eMail or Username'%><br>
        <%= user_form_builder.password_field :password, :class => 'form-control input-xs', :placeholder => 'Passwort'%><br>
        <div class="checkbox pull-left">
          <label class="">
            <input type="checkbox"> Angemeldet bleiben
          </label>
        </div>
        <%= user_form_builder.submit 'Anmelden', :class => 'btn btn-success btn-xs pull-right'%><br><br>
        oder <button type="button" class="btn btn-success btn-xs">Registrieren</button>
      </div>
    <% end %>

控制器:

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 signed_out
  end
end

路线:

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

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

  post "user/sign_in" => "user#login"
end

我找不到问题。

2 个答案:

答案 0 :(得分:2)

如果无法进行身份验证,则表示您正在呈现sign_in操作。使用render而不是redirect_to,操作不会执行;它只呈现动作的视图。 因此,@user操作中未定义预期的login实例变量,这是导致此错误的原因。

尝试更新login操作,如下所示:

  def login
    ...

    if user
      flash[:notice] = 'Welcome'
      redirect_to :root
    else
      flash[:error] = 'Unknown user. Please check your username and password.'

      # Assign user to instance variable for the `sign_in` view!
      @user = user 

      render :action => "sign_in"
    end
  end

而不是定义额外的变量,您可以选择在user操作中将实例变量替换为@user所有本地login变量。

更新:此问题的最快解决方法是使用提供的参数创建新用户,如下所示:

def login
    ...

    if user
      flash[:notice] = 'Welcome'
      redirect_to :root
    else
      flash[:error] = 'Unknown user. Please check your username and password.'

      # Create new user instance variable for the `sign_in` view!
      @user = User.new(params[:user]) 

      render :action => "sign_in"
    end
  end

答案 1 :(得分:1)

更新login方法如下:

  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.'
       @user = User.new   ## Set @user instance variable
      render :action => "sign_in"
    end
  end

您收到错误,因为在身份验证失败的情况下未设置@user实例变量。

此外,根据 Vee 的建议,您可能希望将user替换为@user。 否则,如果您在身份验证成功的情况下(在根页面上)访问@user,那么您将再次收到错误。