Railstutorial ActionView::Template::Error: undefined method `email' for nil:NilClass
Railstutorial ActionView::Template::Error: undefined method `email' for nil:NilClass
这是我第二次学习 Hartl 教程,只是这次我试图为个人项目修改它。现在我很困惑为什么我无法让我的测试通过(或无法呈现编辑设置页面)。这些问题与 this question 非常相似,除了错误是返回电子邮件而不是小写,我使用的是默认测试套件而不是 Rspec。
错误代码如下:
ERROR["test_unsuccessful_edit", UsersEditTest, 0.7226080000109505]
test_unsuccessful_edit#UsersEditTest (0.72s)
ActionView::Template::Error: ActionView::Template::Error: undefined method `email' for nil:NilClass
app/helpers/users_helper.rb:6:in `gravatar_for'
app/views/users/edit.html.erb:8:in `_app_views_users_edit_html_erb___3727331653542369693_70276142435800'
test/integration/users_edit_test.rb:11:in `block in <class:UsersEditTest>'
并且引用的每个文件:
app/helpers/user_helper
module UsersHelper
# Returns the Gravatar for the given user.
def gravatar_for(user, options = { size: 80 })
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
size = options[:size]
gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
image_tag(gravatar_url, alt: user.name, class: "gravatar")
end
end
app/views/users/edit.html.erb
<% provide(:title, "Edit user") %>
<% provide(:button_text, 'Edit account') %>
<h1>Update your profile</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="gravatar_edit">
<%= gravatar_for @user %>
<a href="http://gravatar.com/emails" target="_blank" rel="noopener noreferrer">change</a>
</div>
<%= render 'form' %>
</div>
</div>
test/integration/users_edit_test.rb
require 'test_helper'
class UsersEditTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
end
test "unsuccessful edit" do
log_in_as(@user)
get edit_user_path(@user)
assert_template 'users/edit'
patch user_path(@user), params: { user: { name: "",
email: "foo@invalid",
password: "foo",
password_confirmation: "bar" } }
assert_template 'users/edit'
end
end
并且,因为这是另一个问题中的问题,所以这里是用户模型的相关部分。如果我添加 '!'最后的 email.downcase 方法,所有其他使用电子邮件的测试都失败了,但没有它,它们都通过了(除了这个)。
app/model/user.rb
class User < ApplicationRecord
attr_accessor :remember_token
before_save :downcase_email
...
private
# Converts email to all lower-case
def downcase_email
self.email = email.downcase
end
这里是用户控制器
app/controllers/user_controller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
log_in @user
flash[:success] = 'Welcome to the Sample App'
redirect_to @user
else
render 'new'
end
end
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
# Handle a successful update.
else
render 'edit'
end
end
您需要在 UsersController#edit
操作中设置 @user
实例变量。像这样
class UsersController < ApplicationController
...
def edit
@user = User.find_by_id(params[:id])
end
...
end
如果这不能解决您的问题,您可以在此处粘贴您的 UsersController
代码,这应该可以帮助我们解决您的问题。但是,为了使您的代码更整洁,您可以使用回调设置 @user 并在某些操作上调用该回调。
这是我第二次学习 Hartl 教程,只是这次我试图为个人项目修改它。现在我很困惑为什么我无法让我的测试通过(或无法呈现编辑设置页面)。这些问题与 this question 非常相似,除了错误是返回电子邮件而不是小写,我使用的是默认测试套件而不是 Rspec。
错误代码如下:
ERROR["test_unsuccessful_edit", UsersEditTest, 0.7226080000109505]
test_unsuccessful_edit#UsersEditTest (0.72s)
ActionView::Template::Error: ActionView::Template::Error: undefined method `email' for nil:NilClass
app/helpers/users_helper.rb:6:in `gravatar_for'
app/views/users/edit.html.erb:8:in `_app_views_users_edit_html_erb___3727331653542369693_70276142435800'
test/integration/users_edit_test.rb:11:in `block in <class:UsersEditTest>'
并且引用的每个文件:
app/helpers/user_helper
module UsersHelper
# Returns the Gravatar for the given user.
def gravatar_for(user, options = { size: 80 })
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
size = options[:size]
gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
image_tag(gravatar_url, alt: user.name, class: "gravatar")
end
end
app/views/users/edit.html.erb
<% provide(:title, "Edit user") %>
<% provide(:button_text, 'Edit account') %>
<h1>Update your profile</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="gravatar_edit">
<%= gravatar_for @user %>
<a href="http://gravatar.com/emails" target="_blank" rel="noopener noreferrer">change</a>
</div>
<%= render 'form' %>
</div>
</div>
test/integration/users_edit_test.rb
require 'test_helper'
class UsersEditTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
end
test "unsuccessful edit" do
log_in_as(@user)
get edit_user_path(@user)
assert_template 'users/edit'
patch user_path(@user), params: { user: { name: "",
email: "foo@invalid",
password: "foo",
password_confirmation: "bar" } }
assert_template 'users/edit'
end
end
并且,因为这是另一个问题中的问题,所以这里是用户模型的相关部分。如果我添加 '!'最后的 email.downcase 方法,所有其他使用电子邮件的测试都失败了,但没有它,它们都通过了(除了这个)。
app/model/user.rb
class User < ApplicationRecord
attr_accessor :remember_token
before_save :downcase_email
...
private
# Converts email to all lower-case
def downcase_email
self.email = email.downcase
end
这里是用户控制器
app/controllers/user_controller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
log_in @user
flash[:success] = 'Welcome to the Sample App'
redirect_to @user
else
render 'new'
end
end
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
# Handle a successful update.
else
render 'edit'
end
end
您需要在 UsersController#edit
操作中设置 @user
实例变量。像这样
class UsersController < ApplicationController
...
def edit
@user = User.find_by_id(params[:id])
end
...
end
如果这不能解决您的问题,您可以在此处粘贴您的 UsersController
代码,这应该可以帮助我们解决您的问题。但是,为了使您的代码更整洁,您可以使用回调设置 @user 并在某些操作上调用该回调。