Javascript 注释删除操作视图::模板::错误(对于nil:NilClass,未定义方法'each';):

Javascript 注释删除操作视图::模板::错误(对于nil:NilClass,未定义方法'each';):,javascript,ruby-on-rails,react-redux,Javascript,Ruby On Rails,React Redux,尝试删除评论时出错500次。在后端,注释会被删除,但会因ActionView::Template::Error(nil:NilClass的未定义方法'each'而出错):即使应填充@comments。我使用了window.location.reload(),效果很好。有什么办法可以补救吗 日志 表象成分 import React from 'react'; class CommentIndex extends React.Component { constructor(props)

尝试删除评论时出错500次。在后端,注释会被删除,但会因ActionView::Template::Error(nil:NilClass的未定义方法'each'而出错):即使应填充@comments。我使用了window.location.reload(),效果很好。有什么办法可以补救吗

日志

表象成分

import React from 'react';

class CommentIndex extends React.Component {

    constructor(props) {
        super(props)
        this.handleDelete = this.handleDelete.bind(this);
    }

    componentDidMount() {
        this.props.fetchComments();
    }

    componentDidUpdate(prev) {
        if (Object.values(prev.comments).length !== Object.values(this.props.comments).length) {
            this.props.fetchComments();
        }
    }

    dateCreated(date) {
        const dateCreated = new Date(date)
        return dateCreated.toLocaleDateString();
    }

    authorInitial(id) {
        const users = Object.values(this.props.state.entities.users);
        const user = users.filter(user => user.id === id);
        return user[0].username.split("")[0]
    }

    authorName(id) {
        const users = Object.values(this.props.state.entities.users);
        const user = users.filter(user => user.id === id);
        return user[0].username
    }

    handleDelete(id) {
        this.props.deleteComment(id)
            // .then(window.location.reload())
    }

    render() {
        const comments = Object.values(this.props.state.entities.comments);
        const videoComments = comments.filter(comment => comment.video_id === this.props.id)

        const commentNumber = function () {
            if (videoComments.length === 1) {
                return "1 Comment"
            } else {
                return `${videoComments.length} Comments`
            }
        }
        const commentList = videoComments.map(comment => {
            return (
                <ul key={comment.id} >
                    <div className="comment-list-item">
                        <div id="left-side">
                            <h2 className="comment-author-initial">{this.authorInitial(comment.author_id)}</h2>
                            <div className="comment-body">
                                <div className="name-date">
                                    <h2 className="comment-author-name">{this.authorName(comment.author_id)}</h2>
                                    <h2 className="comment-upload-date"> commented on {this.dateCreated(comment.created_at)}</h2>
                                </div>
                                <h2 className="comment-text">{comment.body}</h2>
                            </div>
                        </div>
                            {/* {this.props.currentUser.id === comment.author_id ? <button id="delete-button"onClick={() => this.handleDelete(comment.id)}>Edit</button> : null}     */}
                            {this.props.currentUser.id === comment.author_id ? <button id="delete-button"onClick={() => this.handleDelete(comment.id)}>Delete</button> : null}    
                        
                    </div>
                
                </ul>
            )
        })

        return (
            <div id="comment-list">
                <h1 className="comment-page-title">{commentNumber()}</h1>
                <div className="comment-page-container">
                    <ul id="comment-ul">
                        <div id="comment-page-list">{commentList}</div>
                    </ul>
                </div>
            </div>
        )
    }
}

export default CommentIndex;
从“React”导入React;
类CommentIndex扩展了React.Component{
建造师(道具){
超级(道具)
this.handleDelete=this.handleDelete.bind(this);
}
componentDidMount(){
this.props.fetchComments();
}
组件更新(上一个){
if(Object.values(prev.comments).length!==Object.values(this.props.comments).length){
this.props.fetchComments();
}
}
创建日期(日期){
const dateCreated=新日期(日期)
return dateCreated.toLocaleDateString();
}
作者(id){
const users=Object.values(this.props.state.entities.users);
const user=users.filter(user=>user.id==id);
返回用户[0]。用户名。拆分(“”[0]
}
authorName(id){
const users=Object.values(this.props.state.entities.users);
const user=users.filter(user=>user.id==id);
返回用户[0]。用户名
}
handleDelete(id){
this.props.deleteComment(id)
//.then(window.location.reload())
}
render(){
const comments=Object.values(this.props.state.entities.comments);
const videoComments=comments.filter(comment=>comment.video\u id===this.props.id)
const commentNumber=函数(){
如果(videoComments.length==1){
返回“1条评论”
}否则{
返回`${videoComments.length}注释`
}
}
const commentList=videoComments.map(comment=>{
返回(
    {this.authorInitial(comment.author_id)} {this.authorName(comment.author_id)} 对{this.dateCreated(comment.created_at)}发表了评论 {comment.body} {/*{this.props.currentUser.id==comment.author_id?this.handleDelete(comment.id)}>Edit:null}*/} {this.props.currentUser.id==comment.author\u id?this.handleDelete(comment.id)}>Delete:null}
) }) 返回( {commentNumber()}
    {commentList}
) } } 导出默认索引;
控制器

class Api::CommentsController < ApplicationController

    def index
        @comments = Comment.all
        render :index
    end

    def new
        @comment = Comment.new
        render :new
    end

    def show
        @comment = Comment.find(params[:id])
        render :show
    end

    def create
        @comment = Comment.new(comment_params)
        @comment.author_id = current_user.id 
        if @comment.save
            render :show
        else
            render json: @comment.errors.full_messages , status: 422
        end
    end

    def update
        @comment = Comment.find(params[:id])
        if @comment.update(comment_params)
            render :show
        else
            render json: @comment.errors.full_messages, status: 422
        end
    end

    def destroy
        @comment = Comment.find(params[:id])
        @comment.destroy
        render :index
    end

    def comment_params 
        params.require(:comment).permit(:body, :author_id, :video_id)
    end
end
class Api::CommentsController
问题的原因不言而喻:

def destroy
  @comment = Comment.find(params[:id])
  @comment.destroy
  render :index
end
render:index
非常非常规。您可能是一个非常常见的误解的受害者-
render:index
不调用控制器中的index方法。它只是渲染视图

在经典的Rails应用程序中,销毁资源通常会重定向到索引

def destroy
  @comment = Comment.find(params[:id])
  @comment.destroy
  redirect_to :index, notice: 'Comment deleted.'
end
如果您正在创建一个服务于JSON的控制器,您通常会使用一个响应代码进行响应:

def destroy
  @comment = Comment.find(params[:id])
  @comment.destroy
  head :no_content
end
但是,如果请求主体包含一个类似于描述状态的JSON的实体,您也可以使用
200-OK
进行响应

通过使用,您可以同时执行以下两项操作:

def destroy
  @comment = Comment.find(params[:id])
  @comment.destroy
  respond_to do |f|
    f.html { redirect_to :index }
    f.json { head :no_content }
  end
end

“即使@comments应该被填充”-你为什么这么认为?显示控制器操作。从销毁操作,您正在呈现索引视图,但不是设置
@comments
。因此出现了错误。我添加了@comments=Comment.all,在12毫秒内完成了422个不可处理的实体(视图:0.1毫秒|活动记录:1.6毫秒)
def destroy
  @comment = Comment.find(params[:id])
  @comment.destroy
  respond_to do |f|
    f.html { redirect_to :index }
    f.json { head :no_content }
  end
end