質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

3974閲覧

Ruby on RailsでMissingTemplateエラー(form_forのルーティング)

pukotan

総合スコア11

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

1クリップ

投稿2017/11/07 05:27

編集2017/11/09 06:39

試行錯誤した結果、Web上ではエラーが出なくなったのですが、テストを実行すると
MissingTemplateというエラーが出ます。

●コントローラ

Ruby

1 def edit 2 @user = User.find(params[:user_id]) 3 end 4 5 def update 6 @user = User.find(params[:user_id]) 7 if @user.update_attributes(user_params) 8 flash[:success] = "登録情報を更新しました" 9 redirect_to @user 10 elsif 11 render edit_user_setting_path(@user) 12 end 13 end

●テスト

Ruby

1 test "unsuccessful setting edit" do 2 log_in_as(@user) 3 get edit_user_setting_path(@user) 4 patch user_setting_path(@user), params: { user: { name: "", 5 email: "foo@invalid", 6 password: "foo", 7 password_confirmation: "bar" } } 8 assert_redirected_to @user 9 end

getまではテストが成功するのですが、patchの部分でエラーが出ます。
でも、コントローラのupdateにdebuggerを挿入してみたところ、paramsはテストで入力した値に変更されており、@user.update_attributes(user_params)もtrueでした。

●エラーメッセージ

ActionView::MissingTemplate: ActionView::MissingTemplate: Missing template users/762146111/setting/edit with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder]}. Searched in: * "/home/ubuntu/workspace/fashion_search/app/views" app/controllers/users/settings_controller.rb:16:in `update' test/integration/users_edit_test.rb:13:in `block in <class:UsersEditTest>'

●ルーティング(config/routes.rb)

Ruby

1resources :users do 2 resource :setting, only:[ :edit, :update ], controller: 'users/settings' 3end

●現状のルーティング($ rails routesの結果)

Ruby

1edit_user_setting GET /users/:user_id/setting/edit(.:format) users/settings#edit 2 user_setting PATCH /users/:user_id/setting(.:format) users/settings#update 3 PUT /users/:user_id/setting(.:format) users/settings#update

●ビュー(app/views/users/settings/edit.html.erb)
以前はWeb上でもエラーが出ていたのですが、上から3行目のurlをusers_pathからuser_setting_pathに修正したところ、Web上ではエラーが出なくなりました。

Ruby

1<% provide(:title, "ユーザー設定変更") %> 2<% provide(:button_text, '変更を保存') %> 3<% provide(:url, user_setting_path) %> 4<h1>ユーザー登録情報の編集</h1> 5 6<div class="row"> 7 <div class="col-md-6 col-md-offset-3"> 8 <%= render 'users/form' %> 9 <div class="gravatar_edit"> 10 <%= gravatar_image_tag @user %> 11 <a href="http://gravatar.com/emails" target="_blank" rel="noopener" >変更</a> 12 </div> 13 </div> 14</div>

●ビュー(app/views/users/_form.html.erb)

Ruby

1<%= form_for(@user, url: yield(:url)) do |f| %> 2 <%= render 'shared/error_messages', object: @user %> 3 4 <%= f.label :name, "名前" %> 5 <%= f.text_field :name, class: 'form-control' %> 6 7 <%= f.label :email, "Eメールアドレス" %> 8 <%= f.email_field :email, class: 'form-control' %> 9 10 <%= f.label :password, "パスワード" %> 11 <%= f.password_field :password, class: 'form-control' %> 12 13 <%= f.label :password_confirmation, "パスワードの確認" %> 14 <%= f.password_field :password_confirmation, class: 'form-control' %> 15 16 <%= f.submit yield(:button_text), class: "btn btn-primary" %> 17<% end %>

Web上ではエラーが出ないのにテストでエラーが出るのはなぜでしょうか?
テストの書き方に問題があるのか、ルーティングがよくないのか、ほかのところに原因があるのか・・・。
どなたかわかる方、お願いします!

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

エラー原因は、renderの使い方が間違っていたことでした。

コントローラをprintデバッグしたところ、コントローラは、意図したとおり1→2→3→6→7行目の順に処理されていることがわかりました。
また、@userの値をチェックしたところ、elsifの前後で値が変わっていることがわかりました。
さらに、elsifの後にputsを入れたところ、エラー内容が変わりました(下記参照)。

コントローラ

Ruby

11 def update 22 @user = User.find(params[:user_id]) ← fixtureで定義済みの@user 33 if @user.update_attributes(user_params) ← false 44 flash[:success] = "登録情報を更新しました" 55 redirect_to @user 66 elsif 77 puts "1"  ← テストで再定義した名無しユーザー 88 render edit_user_setting_path(@user) 99 end 1010 end

エラー

Ruby

1test_unsuccessful_setting_edit#UsersEditTest (0.63s) 2 Expected response to be a <3XX: redirect>, but was a <204: No Content> 3 Response body: 4 test/integration/users_edit_test.rb:17:in `block in <class:UsersEditTest>'

したがって、8行目のrenderに問題があると判断してrenderの使い方を調べました。
(参考URL https://railsguides.jp/layouts_and_rendering.html)
すると、同じコントローラ内の別のアクションのテンプレートを表示したいときには、render :actionまたはrender "action"と書けばよいことがわかりました。

修正したところ、テストのエラー箇所がupdateから、その次の行のassert_redirected_to @userに変わりました。
コントローラでリダイレクトをしていないので、assert_redirected_toをassert_templateに修正し、リダイレクト先がユーザーページでなく編集ページなので@userから:editに変更したところ、エラーが出なくなり、Web上でも問題なく動作するようになりました。

修正後のコントローラ

Ruby

1 def update 2 @user = User.find(params[:user_id]) 3 if @user.update_attributes(user_params) 4 flash[:success] = "登録情報を更新しました" 5 redirect_to @user 6 elsif 7 render :edit 8 end 9 end

修正後のテスト

Ruby

1test "unsuccessful setting edit" do 2 log_in_as(@user) 3 get edit_user_setting_path(@user) 4 patch user_setting_path(@user), params: { user: { name: "", 5 email: "foo@invalid", 6 password: "foo", 7 password_confirmation: "bar" } } 8 assert_template :edit 9end

投稿2017/11/10 03:07

編集2017/11/10 04:01
pukotan

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問