Railsで発生した「undefined local variable or method」エラーを直したいです。
- 評価
- クリップ 2
- VIEW 25K+
前提・実現したいこと
該当箇所とされるファイルを一通り確認しても問題箇所が見つからず、困っています。
rails初心者です。
発生している問題・エラーメッセージ
Railsチュートリアル10章のリスト10.26より、
rails testを走らせた時に10errorが発生しました。
(直近テスト リスト10.22はエラー無し)
1) Error:
UsersEditTest#test_successful_edit:
NoMethodError: undefined method `logged_in_user' for #<UsersController:0x007fa114dbe2e8>
Did you mean? logged_in?
test/integration/users_edit_test.rb:25:in `block in <class:UsersEditTest>'
2) Error:
UsersEditTest#test_unsuccessful_edit:
NoMethodError: undefined method `logged_in_user' for #<UsersController:0x007fa114d6cfd8>
Did you mean? logged_in?
test/integration/users_edit_test.rb:12:in `block in <class:UsersEditTest>'
3) Error:
UsersControllerTest#test_should_redirect_edit_when_logged_in_as_wrong_user:
NoMethodError: undefined method `logged_in_user' for #<UsersController:0x00000006b5e658>
Did you mean? logged_in?
test/controllers/users_controller_test.rb:33:in `block in <class:UsersControllerTest>'
4) Error:
UsersControllerTest#test_should_redirect_update_when_logged_in_as_wrong_user:
AbstractController::ActionNotFound: The action 'update' could not be found for UsersController
test/controllers/users_controller_test.rb:40:in `block in <class:UsersControllerTest>'
5) Error:
UsersControllerTest#test_should_get_new:
ActionView::Template::Error: First argument in form cannot contain nil or be empty
app/views/users/new.html.erb:5:in `_app_views_users_new_html_erb__4200017072968446905_56780960'
test/controllers/users_controller_test.rb:11:in `block in <class:UsersControllerTest>'
8) Error:
UsersLoginTest#test_login_with_valid_information_followed_by_:
ActionView::Template::Error: undefined method `name' for nil:NilClass
app/views/users/show.html.erb:1:in `_app_views_users_show_html_erb__1377065752919381560_58665040'
test/integration/users_login_test.rb:24:in `block in <class:UsersLoginTest>'
9) Error:
UsersSignupTest#test_valid_signup_information:
ActionView::Template::Error: First argument in form cannot contain nil or be empty
app/views/users/new.html.erb:5:in `_app_views_users_new_html_erb__4200017072968446905_56780960'
test/integration/users_signup_test.rb:16:in `block in <class:UsersSignupTest>'
32 runs, 47 assertions, 0 failures, 10 errors, 0 skips
(字数制限により同じファイルからのエラーは一部省略してます)
該当のソースコード
テスト(10章で実装したもの)
①UsersEditTest
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
# 成功時
test "successful edit" do
log_in_as(@user)
get edit_user_path(@user)
assert_template 'users/edit'
name = "Foo Bar"
email = "foo@bar.com"
patch user_path(@user), params: { user: { name: name,
email: email,
password: "",
password_confirmation: "" } }
assert_not flash.empty?
assert_redirected_to @user
@user.reload
assert_equal name, @user.name
assert_equal email, @user.email
end
end
②UsersControllerTest
require 'test_helper'
class UsersControllerTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
@other_user = users(:archer)
end
test "should get new" do
get signup_path
assert_response :success
end
test "should redirect edit when not logged in" do
get edit_user_path(@user)
assert_not flash.empty?
assert_redirected_to login_url
end
test "should redirect update when not logged in" do
patch user_path(@user), params: { user: { name: @user.name,
email: @user.email } }
assert_not flash.empty?
assert_redirected_to login_url
end
# 他人が入った場合の失敗テスト
test "should redirect edit when logged in as wrong user" do
log_in_as(@other_user) # 例 archerさんが入った場合
get edit_user_path(@user)
assert flash.empty?
assert_redirected_to root_url
end
test "should redirect update when logged in as wrong user" do
log_in_as(@other_user) # 例 archerさんが入った場合
patch user_path(@user), params: { user: { name: @user.name,
email: @user.email } }
assert flash.empty?
assert_redirected_to root_url
end
end
(③test_helper.rb)
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
# テストユーザーがログイン中の場合にtrueを返す
def is_logged_in?
!session[:user_id].nil?
end
# テストユーザーとしてログインする
def log_in_as(user)
session[:user_id] = user.id
end
end
class ActionDispatch::IntegrationTest
# テストユーザーとしてログインする
def log_in_as(user, password: 'password', remember_me: '1')
post login_path, params: { session: { email: user.email,
password: password,
remember_me: remember_me } }
end
end
ファイル(10章で実装したもの)
①UsersController
class UsersController < ApplicationController
before_action :logged_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
# 上から順に行う
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
# GET => redirect_to "/user/#{@user.id}" => show
else
render "new"
end
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params) #下のバリデーション
# Success
flash[:success] = "Profile updated"
redirect_to @user
else
# Failure
# => @user.errors.full_messages()
render 'edit'
end
end
private
def user_params
params.require(:user).permit(
:name, :email, :password,
:password_confirmation)
end
# beforeアクション
# ログイン済みユーザーかどうか確認
def logged_in_user
unless logged_in?
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# 正しいユーザーかどうか確認
def correct_user
# GET edit
# PATCH update
@user = User.find(params[:id])
redirect_to(root_url) unless @user == current_user
end
end
②edit.html.erb
<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(@user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Save changes", class: "btn btn-primary" %>
<% end %>
<div class="gravatar_edit">
<%= gravatar_for @user %>
<a href="http://gravatar.com/emails" target="_blank">change</a>
</div>
</div>
</div>
試したこと
①ルーティング
実際にプレビューでブラウザに入り、
Homeから新規登録ページに行くと以下のエラーメッセージが出ました。
エラーメッセージに「Routing Error」とあったので、
routesを確認しました。
Rails.application.routes.draw do
get 'sessions/new'
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users
end
signup_pathとnew_user_pathがあることで、
これらのnewアクションへの重複によるものかと思いました。
signup GET /signup(.:format) users#new
new_user GET /users/new(.:format) users#new
ただ、home.html.erbを見るとsignup_pathへ送っていて、
またRailsチュートリアルでも特に問題ないとのことだったので、
違うと判断しました。
②誤字
リスト10.22〜10.26間でエラーが発生したため、
実装したチュートリアル内のコードを再度コピペし直しタイプミス等確認しましたが、エラーのままでした。
念のため10章の内容全てをコピペし直しましたが、変わりませんでした。
補足情報(FW/ツールのバージョンなど)
長文すみません。
1日調べましたが解決できず、先に進めなくて困っています。
ご協力お願いします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+2
恐らくUserControllerのどこかに全角の空白が含まれているのだと思います。
全角空欄がないか、検索をして調べてみてください。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.34%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2019/01/15 22:52
本当に助かりました!ありがとうございます!!!