Railstutorial ActionView :: Template ::错误:未定义的方法`email'为零:NilClass

时间:2017-01-30 08:56:42

标签: ruby-on-rails railstutorial.org

我第二次完成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>'

引用的每个文件:

应用程序/助手/ 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

应用程序/视图/用户/ 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>

测试/集成/ 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

而且,因为这是另一个问题中的问题,这里是用户模型的相关部分。如果我添加&#39;!&#39;到最后的email.downcase方法,所有其他使用电子邮件的测试都失败了,但没有它们都会通过(除了这个)。

应用程序/模型/ 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

1 个答案:

答案 0 :(得分:2)

您需要在@user操作中设置UsersController#edit实例变量。像这样

class UsersController < ApplicationController 
...
  def edit
    @user = User.find_by_id(params[:id]) 
  end 
...
end 

如果这不能解决您的问题,您可以在此处粘贴UsersController代码,以帮助我们解决您的问题。但是,为了使代码更整洁,您可以使用回调设置@user并在某些操作上调用该回调。