Search code examples
ruby-on-railsdestroylink-to

link_to and the destroy method


I have an app where you add games (found via API) to a user's library, but I also want the user to delete games from a library. However I am not sure if I am using the correct link_to path or if the issue is with my controller.

Routes

Rails.application.routes.draw do
  get 'library_game/index'
  devise_for :users
  root to: 'pages#home'
  get '/games', to: 'games#index', as: :index
  get '/user/:id', to: 'user#show'
  resource :user, only: [] do
  resources :games, only: [:create, :destroy]
end
  get '/user/:id/library', to: 'library#index', as: :library
  post '/user/:id/library', to: 'games#create', as: :create
  delete 'user/:id/library', to: 'games#destroy', as: :destroy
end

My game model

class Game < ApplicationRecord
  has_many :library_games
  has_many :libraries, through: :library_games
  has_many :users, through: :libraries
  serialize :data
  attr_accessor :game_id

  def fetch_data
    game = GiantBomb::Game.detail(game_id)
    self.data = Hash[game.instance_variables.map { |var| [var.to_s[1..-1], game.instance_variable_get(var)] } ]
  end

  def to_giant_bomb_game
    GiantBomb::Game.new(data)
  end
end

My link_to for deleting:

<%= link_to 'Remove from library', destroy_path(current_user, game_id: game.id), method: :delete %>

My controller method for destroy:

def destroy
    current_user.games.where(game_id: params[:id]).destroy_all
    redirect_to library_path
  end

With what I have now, I am getting this error: ActiveRecord::StatementInvalid in GamesController#destroy PG::UndefinedColumn: ERROR: column games.game_id does not exist

So the error throws up an issue with the controller, but I am wondering if the real culprit is that my link_to is not passing the correct data. What should I be passing to my link_to?


Solution

  • If the connection is LibraryGame (as in it has a library_id and a game_id) then this

    resource :user, only: [] do
      resources :games, only: [:create, :destroy]
    end
    

    needs to be

    resources :users, only: [] do
      resources :library_games, only: [:create, :destroy], shallow: true
    end
    

    The shallow: true, gives you routes like users/1/library_games/x for index, create, and new, but routes like library_games/x for show, edit, update, and destroy. Best of both worlds.

    And then your link would be <%= link_to "Remove from Library", library_game_path(library_game), method: :delete %>.