Reputation: 899
I'm working through the Hartl tutorial for the second time only this time I'm trying to modify it for a personal project. Now I'm stumped as to why I can't get my test to pass (or the edit settings page to render). The issues is very similar to this question except the error is returning for email and not downcase and I'm using the default test suite and not Rspec.
Here is the error code:
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>'
And each file referenced:
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
And, because it was the issue in the other question, here is the relevant part of the user model. If I add '!' to the email.downcase method at the end, all the other tests that use email fail, but without it they all pass (except this one).
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
Here is the user controller
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
Upvotes: 0
Views: 2145
Reputation: 1941
You will need to set @user
instance variable in your UsersController#edit
action. Like so
class UsersController < ApplicationController
...
def edit
@user = User.find_by_id(params[:id])
end
...
end
If this does not solve your problem, you can paste your UsersController
code here that should help us solve your problems. However to make your code neater, you can set @user using a callback and call that callbacks on certain actions.
Upvotes: 2