Rails отображает частичный вид, когда он должен обновлять только частичный вид на существующей странице

#javascript #ajax #ruby-on-rails-4 #partials

#javascript #ajax #ruby-on-rails-4 #частичные

Вопрос:

Я пытаюсь реализовать голосование вверх / вниз за публикацию через AJAX, чтобы пользователям не приходилось обновлять страницу, чтобы увидеть обновленный результат. Однако при нажатии на ссылки для голосования пользователь перенаправляется на страницу, которая отображает только частичный вид. Родительский вид даже не отображается. Как я могу обновить частичный вид на индексной странице без обновления всей страницы? Я подозреваю, что проблема заключается в моем действии контроллера ‘vote’. Вот мой код на данный момент:

/app/controllers/posts_controllers.rb

 def vote
  value = params[:type] == "up" ? 1 : -1
  @post = Post.find(params[:id])
  @post.add_or_update_evaluation(:votes, value, current_user)
  respond_to do |format|
    #I'm guessing the problem lies here.
    format.html { render partial: 'score', locals: {post: @post} }
    format.js
  end
end
  

/app/views/posts/_score.html.erb

 <td id="score_<%= post.id %>"><%= post.reputation_for(:votes).to_i %></td>
<% if user_signed_in? %>
<td>
  <%= button_to "Upvote", vote_post_path(post, type: "up"), method: "post", class: "btn btn-success", remote: true %>
</td>
<td>
  <%= button_to "Downvote", vote_post_path(post, type: "down"), method: "post", class: "btn btn-danger", remote: true %>
</td>
<% end %>
  

/app/views/posts/score.js.erb

 $('#score_<%= post.id %>').html("<%= escape_javaScript render partial: 'score', locals: {post: @post} %>");
  

/app/views/posts/index.html.erb

 <% @posts.each do |post| %>
  <%= render partial: 'score', locals: {post: post} %>
  ...
<% end %>
  

/app/assets/javascripts/application.js

 //= require jquery
//= require jquery_ujs
//= require bootstrap.min
//= require turbolinks
//= require_tree .
  

Комментарии:

1. Я предполагаю, что он не проходит через javascript, а ссылка — это просто обычный якорь.

2. «Ссылка» — это Rails button_to . Обратите внимание, что я добавил remote: true атрибут к кнопке. Есть идеи, как устранить это?

Ответ №1:

js В ветке вашего ответа отсутствует блок, в котором указывается, какой вид должен быть отображен:

 respond_to do |format|
  format.html { render partial: 'score', locals: {post: @post} }
  format.js { render partial: 'score', locals: {post: @post} }
end
  

В противном случае rails по умолчанию будет отображать vote.js , поскольку это имя вашего метода контроллера. И, возможно, это просто опечатка, но ваш файл должен быть назван _score.js.erb (частично), точно так же, как версия HTML.

Обновить

Еще раз просмотрев ваш код, возможно, достаточно просто переименовать score.js.erb в vote.js.erb , поскольку вы отображаете _score частичное там.

И с точки зрения дизайна, самым чистым и сухим решением было бы пропустить блоки для format вызовов и иметь файлы, подобные таким:

 # posts_controllers.rb
def vote
  value = params[:type] == "up" ? 1 : -1
  @post = Post.find(params[:id])
  @post.add_or_update_evaluation(:votes, value, current_user)

  respond_to do |format|
    format.html  # this renders vote.html.erb
    format.js    # this renders vote.js.erb
  end
end


# vote.html.erb
<%= render 'score', locals: { post: @post } %>


# vote.js.erb
$('#score_<%= @post.id %>').html("<%= escape_javaScript render partial: 'score', locals: { post: @post } %>");


# _score.html.haml
<td id="score_<%= post.id %>"><%= post.reputation_for(:votes).to_i %></td>
<% if user_signed_in? %>
<td>
  <%= button_to "Upvote", vote_post_path(post, type: "up"), method: "post", class: "btn btn-success", remote: true %>
</td>
<td>
  <%= button_to "Downvote", vote_post_path(post, type: "down"), method: "post", class: "btn btn-danger", remote: true %>
</td>


# index.html.erb
<%= render 'score', collection: @posts, as: :post %>
  

Комментарии:

1. Я внес изменения, которые вы указали в обновлении в своих сообщениях. Однако переход к /posts приводит к неопределенной локальной переменной или методу `post’ для #<#<Class:0x49bbfe8>:0x4760bb0> .

2. Кроме того, я вместо этого попытался отменить эти изменения и выполнить только те изменения, которые вы предложили перед редактированием. Опять же, в браузере отображается только частичный вид.