NoMethodError (неопределенный метод destroy для nil: NilClass): даже если он определен - PullRequest
0 голосов
/ 11 декабря 2018

Это компонент, над которым я сейчас работаю:

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 (неопределенный метод `destroy 'для nil: NilClass):

app / controllers / api / board_games_controller.rb: 30: в `destroy '

и консоль дает мне:

xhr.js: 178DELETE 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 голосов
/ 11 декабря 2018

Ваша ошибка гласит:

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'

Ошибка не имеет ничего общего сдействие destroy не определено.Имеется в виду, как уже говорилось, @board_game, равное нулю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...