NoMethodError(nil:NilClass的未定义方法“ destroy”):即使已定义

时间:2018-12-11 20:33:47

标签: ruby-on-rails reactjs

这是我目前正在使用的组件:

import React, { Component } from 'react';
import axios from 'axios'; 
import { connect } from 'react-redux';
import { Button, Card, Container } from 'semantic-ui-react'

class Games extends Component {

  state = { games:[], user_games: [], showGames: false }

  componentDidMount() {
    const userId = this.props.user.id 
    axios.get('/api/board_games')
      .then(res => {
        this.setState({games: res.data});
      })
    axios.get(`/api/users/${userId}/board_games`)
      .then(res => {
        console.log(res.data); 
        this.setState({user_games: res.data});
      } )

  }

  toggleGames = () => {
    this.setState({ showGames: !this.state.showGames })
  }

  removeGame = (id) => {
    const {userId} = this.props.user.id 
    axios.delete(`/api/users/${userId}/board_games/${id}`)
      .then(res => {
        console.log(res);
        console.log(res.data); 
      })
  }

  addGame = (id) => {
    const {userId} = this.props.user.id 
    axios.post(`api/users/${userId}/board_games`, { userId, id })
      .then(res => {
        console.log(res);
      })
  }

  userLibrary = () => {
    const {user_games} = this.state 
    return user_games.map( game => 
      <Card key={game.id}>
        <Card.Content>
          <Card.Header>{game.title}</Card.Header>
          <Card.Description>Players: {game.min_players} - {game.max_players}</Card.Description>
          <Card.Description>Company: {game.company}</Card.Description>
          <Card.Description>Time Needed: {game.time_needed}</Card.Description>
        </Card.Content>
        <Card.Content extra> 
              <Button basic color='red' onClick={() => this.removeGame(game.id)}>
                Remove from Library
              </Button>
          </Card.Content>
      </Card> 
    )
  }

  gamesList = () => {
    const { games, user_games } = this.state 
    return games.map( game =>
        <Card key={game.id}>
          <Card.Content>
            <Card.Header>{game.title}</Card.Header>
            <Card.Description>Players: {game.min_players} - {game.max_players}</Card.Description>
            <Card.Description>Company: {game.company}</Card.Description>
            <Card.Description>Time Needed: {game.time_needed}</Card.Description>
          </Card.Content>
          { user_games.include ? (
          <Card.Content extra>
              <Button basic color='green' onClick={() => this.addGame(game.id)}>
                Add to Library
              </Button>
          </Card.Content>
          ) 
            : (
          <Card.Content extra> 
              <Button basic color='red' onClick={() => this.removeGame(game.id)}>
                Remove from Library
              </Button>
          </Card.Content>
          )  
          }
        </Card> 
      )
  }

  render() {
    const { showGames } = this.state 
    return (
      <Container>
        <h1>Games</h1>
        <h3>Your Games</h3> 
        <Card.Group itemsPerRow={4}>{this.userLibrary()}</Card.Group>
        { showGames ? (
            <div>
              <Button basic onClick={this.toggleGames}>Done Adding</Button>
              <Card.Group itemsPerRow={4}>{this.gamesList()}</Card.Group> 
            </div>
        )
          : (
          <Button basic onClick={this.toggleGames}>Add a Game</Button>
        ) 
        }
      </Container>
    )
  }
}

const mapStateToProps = state => {
  return { user: state.user };
};

export default connect(mapStateToProps)(Games);

当我单击“从库中删除”时,我的服务器给了我:

NoMethodError(nil:NilClass的未定义方法“ destroy”):

app / controllers / api / board_games_controller.rb:30:在“破坏”中

并且控制台给了我:

xhr.js:178删除http://localhost:3000/api/users/1/board_games/1 500(内部服务器错误)

但是我的控制器实际上定义了“ destroy”:

class Api::BoardGamesController < ApplicationController
  # before_action :set_board_game

  def index
    render json: BoardGame.all
  end

  def show
    render json: @board_games
  end

  def create
    board_game = BoardGame.new 
    if board_game.save
      render json: board_game 
    else
      render json: board_game.errors
    end 
  end

  def update
    if @board_game.update(board_game_params)
      render json: @board_game 
    else 
      render_error(@board_game)
    end 
  end

  def destroy 
    @board_game.destroy 
  end 

  private 

  # def set_board_game 
  #   @board_game = Board_Game.find(params[:id])
  # end 

  def board_game_params
    params.require(:board_game).permit(
    :title,
    :min_players,
    :max_players,
    :base_game,
    :time_needed,
    :company 
    )
  end 

end

您会注意到before_action和set_board_game已被注释掉。当我取消注释时,组件尝试安装后,axios.get就会失败。

axios.destroy我在做什么错?

(通常,如果您发现其他任何可怕的错误)。

1 个答案:

答案 0 :(得分:1)

您的错误状态:

NoMethodError (undefined method `destroy' for nil:NilClass)

因为您的destroy动作:

def destroy 
  @board_game.destroy 
end

您永远不会实例化@board_game

您注意到,您已注释掉def set_board_game,这可能已经完成了工作。但是目前看来,@board_game为零。

您需要取消对该位的注释,并修复有关axious.get失败的其他评论。或者,直接在您的@board_game方法中设置destroy

  

但是我的控制器实际上定义了“销毁”

该错误与未定义destroy操作无关。如前所述,它是指@board_game为零。