nil的未定义方法`errors':NilClass用于评论

时间:2016-03-07 08:59:18

标签: jquery ruby-on-rails ruby ajax

我正在使用Ajax在我的文章显示页面中创建评论,并且它完美无缺。现在,我想通过使用Ajax来显示注释的错误。但是,现在我收到了错误:

  

nil的未定义方法`errors':NilClass

我在comments_controller.rb中添加了new方法,以确保应用程序知道实例变量注释确实存在,但问题仍然存在。任何建议都将不胜感激。

评论/ create.js.erb

$('#comments').append("<%= j render @comment %>").hide().fadeIn('slow');

// Empty the form
$('#comment_name').val("");
$('#comment_body').val("");

<% if @comment.errors.any? %>
  (".comments-section").html('<%= j(render :partial => 'shared/errors', :object => comment) %>');
<% end %>

comment.rb

class Comment < ActiveRecord::Base
  validates :name, presence: true
  validates :body, presence: true, length: { minimum: 10 }
  acts_as_votable
  belongs_to :article
end

comments_controller.rb

class CommentsController < ApplicationController
  before_action :set_article
  before_action :set_comment, only: [:destroy]
  before_action :login_like, only: [:upvote, :downvote]

  def new
    @comment = @article.comments.build
  end

  def create
    @comment = @article.comments.create(params[:comment].permit(:name, :body))
    if @comment.save
      respond_to do |format|
        format.html { redirect_to(@article) }
        format.js # render 'create.js.erb'
      end
    else
      respond_to do |format|
        format.html { redirect_to(@article) }
        format.js { render status: :500 }
      end
    end
  end

  def destroy
    if @comment.destroy
      respond_to do |format|
        format.html { redirect_to(article_path(@article)) }
        format.js
      end
    end
  end

  def upvote
    if @comment.upvote_from current_user
      respond_to do |format|
        format.html { redirect_to(:back) }
        format.js
      end
    end
  end

  def downvote
    if @comment.downvote_from current_user
      respond_to do |format|
        format.html { redirect_to(:back) }
        format.js
      end
    end
  end

  private

  def set_article
    @article = Article.find(params[:article_id])
  end

  def set_comment
    @comment = @article.comments.find(params[:id])
  end

  def login_like
    unless user_signed_in?
      flash[:danger] = 'You must log in to like or dislike comments!'
    end
  end
end

评论/ _form.html.erb

<%= render 'shared/errors', obj: @comment %>

<%= simple_form_for([@article, @article.comments.build], remote: true) do |f| %>

  <div class="form-group row">
    <div class="col-sm-2">
      <%= f.label :name, class: "form-control-label" %>
    </div>
    <div class="col-sm-4">
      <%= f.text_field :name, class: "form-control", placeholder: "Anyname..." %>
    </div>
  </div>

  <div class="form-group row">
    <div class="col-sm-2">
      <%= f.label :body, class: "form-control-label" %>
    </div>
    <div class="col-sm-10">
      <%= f.text_area :body, rows: 10, class: "form-control", placeholder: "Write a comment..." %>
    </div>
  </div >
  <br>
  <div class="form-group row">
    <div class="col-sm-offset-2 col-sm-10">
      <%= f.submit class: "btn btn-secondary" %>
    </div>
  </div>
<% end %>

视图/共享/ _errors.html.erb

<% if obj.errors.any? %>
  <div class="row">
    <div class="col-sm-9 col-sm-offset-3">
      <div class="card">
        <div class="card-header card-inverse card-danger">
          <div class="card-title">
            <%= pluralize(obj.errors.count, "error") %> prohibited this article from being saved:
            </div>
            <div class="card-text">
              <ul>
                <% obj.errors.full_messages.each do |message| %>
                  <li><%= message %></li>
                <% end %>
              </ul>
            </div>
        </div>
      </div>
    </div>
  </div>
<% end %>

物品/ show.html.erb

<div class="card col-sm-8 col-sm-offset-2 comments-section glassy-comment">
    <h2 style="padding-top: 7px;">
      Comment
    </h2>
    <hr>
    <div id="comments">
      <%= render @article.comments %>
    </div>
    <h3>Add a comment:</h3>
    <div class="comment-wrapper">
      <%= render 'comments/form' %>
    </div>
  </div>
</div>

2 个答案:

答案 0 :(得分:1)

您只在@comment之前设置了destroy

before_action :set_comment, only: [:destroy]

但您也可以在upvotedownvote使用它。

答案 1 :(得分:0)

您正在显示form以在articles/show.html.erb中添加评论,因此需要在@comment操作中定义articles#show

#artcles_controller

def show
  @comment = Comment.new
end

您需要将form作为local params传递给部分

<%= render 'comments/form', comment: @comment %>

最后更改comments/_form.html.erb

中的以下行
<%= render 'shared/errors', obj: @comment %>

<%= render 'shared/errors', obj: comment %>