AJAX Ruby on Rails | частичный не повторный рендеринг - PullRequest
0 голосов
/ 06 января 2019

Привет, я довольно новичок в rails и пытаюсь реализовать AJAX в своем приложении на Rails.

Проблема в том, что когда я отправляю свою форму, создается впечатление, что действие create определенно вызывается, как при обновлении страницы появляется новый элемент, но таблица не обновляется автоматически.

themes / show.html.erb соответствующий код:

<div class="row" id="toberefreshed">
  <%= render('show_partial', :locals => {:topic => @topic}) %>
</div>

themes / _show_partial.html.erb соответствующий код:

<table class = "opinionlist" align="center">
  <% opinions = @topic.opinions %>
  <% cons = opinions.select{|opinion| opinion.type_of == 'con'} %>
  <% pros = opinions.select{|opinion| opinion.type_of == 'pro'} %>
  <tr>
    <% pros.each do |pro|%>
      <td>
        <div class="article-body">
          <%= pro.content %>
        </div>
        <div class="article-meta-details">
          <small>
            Created by: <%= pro.user.username %>
            <%= time_ago_in_words(pro.created_at) %> ago,
          </small>
        </div>
      </td>
    <% end %>
    <% if pros.length < cons.length %>
      <% difference = cons.length - pros.length%>
      <% difference.times do %>
        <%= content_tag(:td) %>
      <% end %>
    <% end %>

    <td><%= render 'opinions/form', opinion: Opinion.new, typeOf: "pro", :topic => @topic %></td>
  </tr>
  <tr>
    <% cons.each do |con|%>
      <td>
        <div class="article-body">
          <%= con.content %>
        </div>
        <div class="article-meta-details">
          <small>
            Created by: <%= con.user.username %>
            <%= time_ago_in_words(con.created_at) %> ago,
          </small>
        </div>
      </td>
    <% end %>
    <% if pros.length > cons.length %>
      <% difference = pros.length - cons.length %>
      <%  puts "DIFFERENCE: " + difference.to_s  %>
      <% difference.times do %>
        <%= content_tag(:td) %>
      <% end %>
    <% end %>
    <td>
      <%= render 'opinions/form', opinion: Opinion.new, typeOf: "con", :topic => @topic %>
    </td>
  </tr>
</table>

Темы / updated_view.js.erb:

$("toberefreshed").html("<%= escape_javascript(render("topics/show_partial", :locals => {:topic => @opinion.topic})) %>");

opinions_controller.rb

class OpinionsController < ApplicationController
  def create
    @opinion = Opinion.new(opinion_params)
    @opinion.user = current_user
    @opinion.topic = Topic.find(params[:to_find_id])
    @opinion.type_of = params[:type_of]
    if @opinion.save
      flash[:success] = 'Opinion Added'
    else
      puts @opinion.errors.full_messages
      flash[:danger] = 'Opinion not Added'
    end
    respond_to do |format|
      format.js
    end
  end
  private
  def opinion_params
    params.require(:opinion).permit(:content)
  end
end

РЕДАКТИРОВАТЬ: мнения / _form.html.erb

<div class="row">
  <div class="col-xs-12">
    <%= form_for(opinion, :html=> {class:"form-horizontal", role:"form"}, remote: true) do |f| %>
      <div class="form-group">
        <div class="col-sm-12">
          <%= f.text_area :content, rows:4, class: "form-control", placeholder: "Opinion" %>
        </div>
      </div>
      <%= hidden_field_tag 'type_of', typeOf %>
      <%= hidden_field_tag :to_find_id, @topic.id %>
      <% puts "ID: " + @topic.id.to_s %>
      <div class="form-group">
        <div class="col-sm-12">
          <%= f.submit %>
        </div>
      </div>
    <% end %>
  </div>
</div>

Большое спасибо за вашу помощь, Raahil

1 Ответ

0 голосов
/ 06 января 2019

В topics/_show_partial.html.erb

заменить

<% opinions = @topic.opinions %> во второй строке

с

<% opinions = topic.opinions %>

Вы передаете переменную topic через локальные данные в партиал, но вы вызываете instance variable @topic, который не существует, когда вы вызываете метод create

Также измените следующее:

<%= render 'opinions/form', opinion: Opinion.new, typeOf: "pro", :topic => @topic %>

К

<%= render 'opinions/form', opinion: Opinion.new, typeOf: "pro", :topic => topic %>


и изменить

<%= render 'opinions/form', opinion: Opinion.new, typeOf: "con", :topic => @topic %>

К

<%= render 'opinions/form', opinion: Opinion.new, typeOf: "con", :topic => topic %>


Итак, ваш In topics/_show_partial.html.erb должен выглядеть следующим образом:

<table class = "opinionlist" align="center">
  <% opinions = topic.opinions %>
  <% cons = opinions.select{|opinion| opinion.type_of == 'con'} %>
  <% pros = opinions.select{|opinion| opinion.type_of == 'pro'} %>
  <tr>
    <% pros.each do |pro|%>
      <td>
        <div class="article-body">
          <%= pro.content %>
        </div>
        <div class="article-meta-details">
          <small>
            Created by: <%= pro.user.username %>
            <%= time_ago_in_words(pro.created_at) %> ago,
          </small>
        </div>
      </td>
    <% end %>
    <% if pros.length < cons.length %>
      <% difference = cons.length - pros.length%>
      <% difference.times do %>
        <%= content_tag(:td) %>
      <% end %>
    <% end %>

    <td><%= render 'opinions/form', opinion: Opinion.new, typeOf: "pro", :topic => topic %></td>
  </tr>
  <tr>
    <% cons.each do |con|%>
      <td>
        <div class="article-body">
          <%= con.content %>
        </div>
        <div class="article-meta-details">
          <small>
            Created by: <%= con.user.username %>
            <%= time_ago_in_words(con.created_at) %> ago,
          </small>
        </div>
      </td>
    <% end %>
    <% if pros.length > cons.length %>
      <% difference = pros.length - cons.length %>
      <%  puts "DIFFERENCE: " + difference.to_s  %>
      <% difference.times do %>
        <%= content_tag(:td) %>
      <% end %>
    <% end %>
    <td>
      <%= render 'opinions/form', opinion: Opinion.new, typeOf: "con", :topic => topic %>
    </td>
  </tr>
</table>

Одна последняя вещь, которую вы можете принять за рекомендацию:

Вы строите много логики внутри своих представлений, например topics/_show_partial.html.erb вы создаете много локальных переменных внутри представления. Я бы порекомендовал использовать другой подход, такой как построение всех ваших переменных в слое между ними перед представлением, например presenters, посмотрите это обсуждение о rails presenters

Для чего нужна папка Rails Presenters?

Views должен оставаться простым и свободным от логики, насколько это возможно

...