错误ActionView :: Template :: Error(nil:NilClass的未定义方法“名称”)

时间:2018-08-27 10:50:41

标签: ruby-on-rails

我正在使用ruby 2.4和rails 5.1.6。

为了学习RoR,我手工制作了用户模型,视图和控制器,而不是使用支架。

填写表单以创建新用户后,我在Rails服务器日志中收到此错误:

Started POST "/users" for 127.0.0.1 at 2018-08-27 15:52:45 +0530
Processing by UsersController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"gdSumxEvNi6ECKBZLFKN9dB/PYLOmixMcf5oYcUGkE1u4iAa/YkJlu7SJbPQNlh6J2SEzR2WeSUT9frhteEOCw==", "user"=>{"name"=>"User1", "email"=>"user1@yahoo.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign Up"}
   (0.2ms)  begin transaction
  User Exists (0.6ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ?  [["email", "user1@yahoo.com"], ["LIMIT", 1]]
  SQL (0.8ms)  INSERT INTO "users" ("name", "email", "password_digest", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["name", "User1"], ["email", "user1@yahoo.com"], ["password_digest", "$2a$10$Efhs2Z2BRa5FCUdSIz6D5.c/eiFQm3JaW818veE644NdoWluRLjoq"], ["created_at", "2018-08-27 10:22:45.636574"], ["updated_at", "2018-08-27 10:22:45.636574"]]
   (1.0ms)  commit transaction
Redirected to http://127.0.0.1:3000/users/1
Completed 302 Found in 93ms (ActiveRecord: 2.6ms)


Started GET "/users/1" for 127.0.0.1 at 2018-08-27 15:52:45 +0530
Processing by UsersController#show as HTML
  Parameters: {"id"=>"1"}
  Rendering users/show.html.erb within layouts/application
  Rendered users/show.html.erb within layouts/application (9.8ms)
Completed 500 Internal Server Error in 32ms (ActiveRecord: 0.0ms)



ActionView::Template::Error (undefined method `name' for nil:NilClass):
    1: 
    2: <h1><%= @user.name %></h1>
    3: <h2><%= @user.email %></h2>

app/views/users/show.html.erb:2:in `_app_views_users_show_html_erb___1408287096995644504_70277415453360'

如您所见,记录已成功保存到数据库,但是以某种方式,@ user变量在到达show.html.erb模板时就被销毁了。

这是users_controller.rb

class UsersController < ApplicationController
  def index
  end

  def show
    byebug
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user
      byebug
    else
      render 'new'
    end
  end

  def edit
  end

  def update
  end

  def destroy
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :password, :password_confirmation)
  end
end

...这是show.html.erb

的内容
<h1><%= @user.name %></h1>
<h2><%= @user.email %></h2>

在user#create动作的byebug断点处@ user.name的输出显示正确的值,但是在user#show动作的第二个byebug断点处,出现此错误:

(byebug) @user.name
*** NoMethodError Exception: undefined method `name' for nil:NilClass

只是为了确保,我制作了第二个应用程序,但是使用了脚手架发电机,并且一切正常。

有什么想法吗?

p.s。

我在用户模型(app / models / user.rb)中编写了一些验证。我将其包括在下面,以防万一...

class User < ApplicationRecord
    validates :name, presence: true
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
    before_save {email.downcase!}
    validates :email, presence: true, 
                        format: {with: VALID_EMAIL_REGEX},
                        uniqueness: {case_sensitive: false}

    validates :password, presence: true, length: {minimum: 6}

    has_secure_password
end

3 个答案:

答案 0 :(得分:2)

我认为您尚未定义@user对象。为此,您可以在@user = User.find_by(id: params[:id])动作中添加show

答案 1 :(得分:2)

如果可以检查您的日志,则提及以下声明:

Started GET "/users/1" for 127.0.0.1 at 2018-08-27 15:52:45 +0530
Processing by UsersController#show as HTML
  Parameters: {"id"=>"1"}

哈希{“ id” =>“ 1”}表示,您正在尝试获取id = 1的用户。 现在,您只需要重新定义show方法,如下所示:

  def show
    @user = User.find_by_id(params[:id])
  end

答案 2 :(得分:1)

您应该在用户控制器的私有区域中定义setter方法

private
def set_user
  @user = User.find(params[:id])
end

并将其添加到控制器中:

before_action :set_user, only: [:show]

您还可以(在before_action中)定义其他需要访问用户对象的方法