Rails link_to は、JS からレンダリングする場合にのみルート一致エラーを発生させます
概要
プレゼンテーションとコメントを受け取りました。各プレゼンテーションには多くのコメントが許可されており、それらのコメントは返信できるので…
私のプレゼンテーション ショーでは、次の方法でコメントを正常に表示しています。
<div id= "container_comments">
<%= render @presentation.comments.where(ancestry: nil) %>
</div>
このようにして、すべてのコメントはこのベースの _comment.html.erb ファイルを使用してレンダリングされます。
<div class="media" id="comment_<%= comment.id %>">
<div class="media-left">
<img src="<%= image_path("comment.png")%>" class="media-object" style="width:45px">
</div>
<div class="media-body">
<h4 class="media-heading"><%=User.find(comment.author_id).username%> <small><i>Publicado: <%=comment.created_at.strftime('%F %T') %></i></small></h4>
<p><%=comment.body%></p>
<%= link_to "Reply", new_comment_congress_category_presentation_comment_path(@congress, @category, @presentation, :parent_id => comment ), :class => "btn", :remote => true, "data-toggle" => "modal", "data-target" => "#mynewcomment"%>
<% replies = Comment.where(ancestry: comment) %>
<% if replies.any? %>
<% replies.each do |reply| %>
<div class="media">
<div class="media-left">
<img src="<%= image_path("reply.png")%>" class="media-object" style="width:45px">
</div>
<div class="media-body">
<h4 class="media-heading"><%=User.find(reply.author_id).username%> <small><i>Publicado: <%=reply.created_at.strftime('%F %T') %></i></small></h4>
<p><%=reply.body%></p>
</div>
</div>
<%end%>
<%end%>
</div>
</div>
ここではすべてが正常に機能し、プレゼンテーションはコメントと返信を適切に読み込みます。問題は、返信の link_to:
<%= link_to "Reply", new_comment_congress_category_presentation_comment_path(@congress, @category, @presentation, :parent_id => comment ), :class => "btn", :remote => true, "data-toggle" => "modal", "data-target" => "#mynewcomment"%>
プレゼンテーションのショー ビューから正しく読み込まれますが、JS ファイルからのレンダリングは許可されておらず、キー [:id] が欠落している「一致するルートがありません」エラーが表示されます。
これが私のjsファイルです:
$("#mynewcomment").modal('hide');
$(".comment_title").val('');
$(".comment_content").val('');
<%if @comment.parent == nil%>
$("#container_comments").append('<%= j render @comment %>');
$("#comment_<%= @comment.id %>").hide().fadeIn(1000);
<%else%>
<%@parent = Comment.find(@comment.parent_id)%>
$("#comment_<%= @parent.id %>").replaceWith('<%= j render @parent %>');
<%end%>
エラーは次のようになります。
ActionView::Template::Error (No route matches {:action=>"new_comment", :category_id=>#<...category info here...>, :congress_id=>#<...congress info here...>, :controller=>"comments", :parent_id=>#<...parent comment info here...>, :presentation_id=>#<...Presentation info here...>}, missing required keys: [:id]):
7: <p><%=comment.body%></p>
8:
9:
10: <%= link_to "Responder", new_comment_congress_category_presentation_comment_path(@congress, @category, @presentation, :parent_id => comment), :class => "btn", :remote => true, "data-toggle" => "modal", "data-target" => "#mynewcomment", :parent_id => comment %>
11:
12: <% replies = Comment.where(ancestry: comment) %>
13: <% if replies.any? %>
app/views/comments/_comment.html.erb:10:in
`_app_views_comments__comment_html_erb__456499711_134033424'
app/views/comments/create.js.erb:5:in
`_app_views_comments_create_js_erb__184660212_140959668'
まったく同じファイルが js を介してレンダリングに失敗するのはなぜだろうかと思います。ご協力に本当に感謝しています。これが私の最初の Rails プロジェクトを完了するための唯一のステップです。またよろしくお願いします。
解決策
リンクは @congress、@category、@presentation 変数に依存しているため、これらの同じ変数が JS テンプレートでも使用できるようにする必要があります。
この種の間違いを犯しにくくするために、ローカル ハッシュを使用して、インスタンス変数の代わりにローカル変数を使用するようにテンプレートを変更できます。
# in _comment.html.erb
<%=
link_to "Reply",
new_comment_congress_category_presentation_comment_path(
congress, category, presentation,
parent_id: comment
)
%>
# in show.html.erb
<%=
render @presentation.comments.where(ancestry: nil),
locals: { congress: @congress, category: @category, presentation: @presentation }
%>
# in whatever.js.erb
<%= j render @comment, locals: { congress: @congress, ... } %>
こうすることで、3 つの必須ローカル変数のうち 1 つでも割り当てに失敗した場合、どれが不足しているのかがエラー メッセージで明示的に通知されます。