Rails和AJAX发表评论

时间:2016-11-21 22:33:44

标签: javascript jquery ruby-on-rails ajax

我有一个简单的博客应用,可以评论视频游戏。用户可以对评论发表评论。

我的问题是,当我尝试在评论页面上使用AJAX(我是一名学生试图自学)发表评论时,该页面会进行全面刷新。数据仍然正确提交,但我必须重新加载页面才能显示评论。

review.js

$(document).ready(function() {
  $('#new_comment').on('submit', function(e) {
     url = this.action

     data = {
      'authenticity_token': $("input[name='authenticity_token']").val(),
      'comment': {
        'content': $("#comment_content").val(),
      'user_id': $("#comment_user_id").val()
      }
    };

    $.ajax({
      type: "POST",
      url: url,
      data: data,
      success: function(response) {
        $('#comments-section ol').append(response);
      }
    });

    e.preventDefault();
  });
});

comments_controller.rb #create action

  def create
    @review = Review.find_by(params[:id])
    @comment = @review.comments.new(comment_params)

    if !current_user
      redirect_to review_oath(@review), alert: "You must be logged in to add a comment"
    else
      @comment.save
      redirect_to @review
    end
  end

  private

  def comment_params
    params.require(:comment).permit(:content, :user_id)
  end

review.show.html.erb

        <div id="comments-section">
          <% if @review.comments.any? %>

            <p>
              <div><br>
                <br>
              <ul>
                <% @review.comments.all.each do |c| %>
                  <h4 class="media-heading"><%= c.user.email %> said</h4> <br><li><p><%= c.content %></p></li>
                <% end %>
              </ul>
            </p>
          <% end %>
        </div>
      </div>

完整的回购在这里,请确保你在AJAX / JQUERY分支上:https://github.com/jchu4483/Rails-Assessment-/tree/ajax/jquery

谢谢,非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

首先,为了确保应用安全,我建议您将身份验证方法移到ApplicationController中的before_action,并跳过它以进行公共操作。

如果您使用devise gem,可以添加:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  before_action :authenticate_user!
end

默认使用此应用程序是安全的。

对于评论更新,我建议您遵循以下方法:

将您的评论创建形成一个AJAX表单,添加远程参数并将其移动到部分:

<强> _form.html.erb

<%= form_for comment, remote: true do |form|%>
  <%=form.hidden_field :review_id, review_id%>
  <%=form.text_field :content%>
  <%=form.submit :save%>
<% end %>

创建评论列表部分:

<强> _comments.html.erb

<table>
  <thead>
    <tr>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <% comments.each do |comment| %>
      <tr>
        <td>
          <%= image_tag comment.user.avatar.url %>
        </td>
        <td>
          <%= comment.content %>
        </td>
      </tr>
    <% end %>
  </tbody>
</table>

所以你的评论页应该是这样的:

<强>评论/ show.html.erb

<div class="review-photo">
  <%= @review.photo %>
</div>
<div class="review-content">
  <%= @review.content %>
</div>
<section class="comments">
  <div class="new-comment-container">
    <%= render 'my_new_comment_form_path', comment: Comment.new, review_id: @review.id %>
  </div>
  <div class="comments-container">
    <%= render 'my_comments_partial_path', comments: @review.comments %>
  </div>
</section>

更新您的评论控制器,以便在创建操作上响应AJAX:

   def create
    format.js do
      @review = Review.find_by(params[:review_id])
      @review.comments << Comment.create(comment_params)
    end
  end

  private

  def comment_params
    params
      .require(:comment)
      .permit(:content)
      .merge(user_id: current_user.id)
  end

此代码有一点重构,以确保评论者是当前用户。

然后你应该创建一个create.js.erb文件来响应create动作,在这个文件中你应该用旧的列表替换旧列表和旧表单:

<强>评论/ create.js.erb

$('.new-comment-container').html("<%= j render 'my_new_comment_form_path', comment: Comment.new, review_id: @review.id%>")
$('.comments-container').html("<%= j render 'my_comments_partial_path', comments: @review.comments%>")

我认为这是一种在rails中使用AJAX表单的简洁方法。