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

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

ただいまの
回答率

88.82%

rails tutorial 13章の演習問題で疑問

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 867

ddd8

score 19

 前提・実現したいこと

Rails Tutorial 13.3.2の演習問題を問いているところ、気になるところがありました。

演習問題は、パーシャルを利用してHOMEページをリファクタリングしろとのことで、以下のように記述したところ、アプリケーションは動くのですがunittestでエラーがでました。

 テストのエラー

Error:
MicropostsInterfaceTest#test_micropost_interface:
ActionView::Template::Error: Missing partial microposts/_logged_in, application/_logged_in with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder]}. Searched in:
  * "/home/ec2-user/environment/sample_app/app/views"

    app/views/static_pages/home.html.erb:2:in `_app_views_static_pages_home_html_erb___2443717471996564898_60904740'
    app/controllers/microposts_controller.rb:12:in `create'
    test/integration/microposts_interface_test.rb:16:in `block (2 levels) in <class:MicropostsInterfaceTest>'
    test/integration/microposts_interface_test.rb:15:in `block in <class:MicropostsInterfaceTest>'

なぜ、以下のコードでは正しくないのでしょうか。

 該当のソースコード(HOMEページ)

<% if logged_in? %>
  <%= render 'logged_in' %>
<% else %>
  <%= render 'without_logged_in' %>
<% end %>

試しに、以下のように、フォルダー名から記述したところテストが正しく動きました。

 試したこと

<% if logged_in? %>
  <%= render 'static_pages/logged_in' %>
<% else %>
  <%= render 'static_pages/without_logged_in' %>
<% end %>

 補足情報(FW/ツールのバージョンなど)

HOMEページのファイルとlogged_in.html.erbやwithout_logged_in.html.erbファイルが置かれているフォルダーは同じなので、フォルダー名を省略しても動くだろうと思うのですが、なぜ正しく動かなかったのか疑問です。

補足情報2

エラーメッセージを見ると
Missing partial microposts/_logged_in, application/_logged_in

とあることから、micropostsコントローラからrenderでstatic_pages/home.html.erbを表示しているのですが、その場合は、renderした元コントローラに対応するview内のパーシャルを探すようになっているのでしょうか。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

ファイル名の先頭にアンダーバーがついてなかったのでは

  • _logged_in.html.erb
  • _without_logged_in.html.erb

追記:
Viewでrenderメソッドを使いパーシャルを呼び出した際のデフォルトの参照先についての質問だと推察します。

AコントローラのBアクションを実行して呼び出したビューテンプレート内で、

<%= render "hoge" %>

と書いてパーシャルを呼び出すと、views/A/_hoge.html.erbを検索します。

参考リンク

今回の場合、MicropostsControllerのcreateアクションからビューを呼び出していますので、
エラー文が示す通り、views/microposts/_logged_in.html.erbを検索します。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/30 15:57

    ご回答ありがとうございます。

    アンダーバーはついていました。
    質問が漠然としていました。
    具体的にはアプリケーション自体は動くのですが、テストでエラーがでました。

    キャンセル

  • 2018/10/01 11:18 編集

    すみません、ちゃんと書いてましたね…;
    指摘ありがとうございます。
    確認なのですが、「アプリケーションは動く」ということは、

    <% if logged_in? %>
    <%= render 'logged_in' %>
    <% else %>
    <%= render 'without_logged_in' %>
    <% end %>

    というソースコードでも
    Railsアプリを起動⇒ブラウザからログイン⇒HOMEページの投稿欄から空データ(不正なデータ)を投稿⇒HOMEページに遷移
    というを操作をした場合にパーシャルは正しく表示されるが、テストではエラーになる、ということでしょうか。

    DaikiTsukaharaさんの書いたソースコード見てないので確かなことは分からないのですが、おそらく今回テストでエラーになった箇所ってmicroposts_interface_test.rbの

    # 無効な送信
    assert_no_difference 'Micropost.count' do
    post microposts_path, params: { micropost: { content: "" } }
    end


    の箇所だと思うのですが…
    で、 app/controllers/microposts_controller.rb が

    class MicropostsController < ApplicationController
    before_action :logged_in_user, only: [:create, :destroy]

    def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
    flash[:success] = "Micropost created!"
    redirect_to root_url
    else
    render 'static_pages/home'
    end
    end

    っていう風になってると思うので、
    要するに空データを投稿した場合、バリデーションに引っかかって'static_pages/home'に飛ばされるから、投稿する前後でユーザの投稿数は変わらないよね、ってのを確認するためのテストだと思うので、これでstatic_pages/home.html.erbを表示した際にMissing partialのエラーになるなら、実際にブラウザで動かした場合もエラーになるんじゃないかと思うのですが…

    それとも「アプリケーションは動く」というのは、ブラウザからHOMEページを表示するだけならエラーにならない、という趣旨でしょうか??

    キャンセル

  • 2018/10/04 21:48 編集

    度々のご解答ありがとうございます。

    ご指摘の通り、「アプリケーションは動く」はブラウザからHOMEページを表示するだけならエラーにならないという趣旨で使いました。

    誤解を招く書き方をしてしまいました。

    trochさんのおかげで、モヤモヤが解決しました。
    こんな拙い質問から求める回答を導き出していただきありがとうございます。

    キャンセル

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

  • ただいまの回答率 88.82%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る