link_to 和销毁方法
link_to and the destroy method
我有一个应用程序,您可以将游戏(通过 API 找到)添加到用户的库中,但我也希望用户从库中删除游戏。但是我不确定我是否使用了正确的 link_to 路径,或者问题是否出在我的控制器上。
路线
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
我的游戏模型
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
我的link_to删除:
<%= link_to 'Remove from library', destroy_path(current_user, game_id: game.id), method: :delete %>
我的销毁控制器方法:
def destroy
current_user.games.where(game_id: params[:id]).destroy_all
redirect_to library_path
end
根据我现在的情况,我收到此错误:ActiveRecord::StatementInvalid in GamesController#destroy
PG::UndefinedColumn:错误:列 games.game_id 不存在
所以错误引发了控制器的问题,但我想知道真正的罪魁祸首是否是我的 link_to 没有传递正确的数据。我应该将什么传递给我的 link_to?
检查 html(使用浏览器中的检查器工具)link link_to 辅助方法正在生成什么。
您在 routes.rb 中有 2 条处理游戏删除的路线,但由于您使用 destroy_path
,这是一条有趣的路线:
delete 'user/:id/library', to: 'games#destroy', as: :destroy
看到 :id
有一个占位符了吗?这是用户 ID,而不是游戏 ID,但是在控制器的销毁操作中,您会查找带有 params[:id]
的游戏,这是用户 ID
...(game_id: params[:id])...
这就是它失败的原因。
您需要清理路线。在上面的那个中,为什么路径 user/:id/library
但它转到了游戏控制器。为什么上面还有一条处理删除游戏的路由?在 rails 上的 ruby 中,一切都与约定有关,您也应该遵循它们。
您还想查看嵌套路由 https://guides.rubyonrails.org/routing.html#nested-resources
对于销毁动作,您通常不需要嵌套路线,因为有了游戏的 ID,您应该能够在数据库中找到它并销毁它。您还设计了可以使用您已经使用的 current_user
的方法。
所以你可以有这样的路线:
resources :games, only: :destroy
然后使用link_to方法
<%= link_to 'Remove from library', game_path(game.id), method: :delete %>
如果连接是 LibraryGame
(因为它有一个 library_id
和一个 game_id
)那么这个
resource :user, only: [] do
resources :games, only: [:create, :destroy]
end
需要
resources :users, only: [] do
resources :library_games, only: [:create, :destroy], shallow: true
end
shallow: true
为您提供了用于索引、创建和新建的路由,如 users/1/library_games/x
,但用于显示、编辑、更新和销毁的路由,如 library_games/x
。两全其美。
然后你的 link 将是 <%= link_to "Remove from Library", library_game_path(library_game), method: :delete %>
。
我有一个应用程序,您可以将游戏(通过 API 找到)添加到用户的库中,但我也希望用户从库中删除游戏。但是我不确定我是否使用了正确的 link_to 路径,或者问题是否出在我的控制器上。
路线
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
我的游戏模型
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
我的link_to删除:
<%= link_to 'Remove from library', destroy_path(current_user, game_id: game.id), method: :delete %>
我的销毁控制器方法:
def destroy
current_user.games.where(game_id: params[:id]).destroy_all
redirect_to library_path
end
根据我现在的情况,我收到此错误:ActiveRecord::StatementInvalid in GamesController#destroy PG::UndefinedColumn:错误:列 games.game_id 不存在
所以错误引发了控制器的问题,但我想知道真正的罪魁祸首是否是我的 link_to 没有传递正确的数据。我应该将什么传递给我的 link_to?
检查 html(使用浏览器中的检查器工具)link link_to 辅助方法正在生成什么。
您在 routes.rb 中有 2 条处理游戏删除的路线,但由于您使用 destroy_path
,这是一条有趣的路线:
delete 'user/:id/library', to: 'games#destroy', as: :destroy
看到 :id
有一个占位符了吗?这是用户 ID,而不是游戏 ID,但是在控制器的销毁操作中,您会查找带有 params[:id]
的游戏,这是用户 ID
...(game_id: params[:id])...
这就是它失败的原因。
您需要清理路线。在上面的那个中,为什么路径 user/:id/library
但它转到了游戏控制器。为什么上面还有一条处理删除游戏的路由?在 rails 上的 ruby 中,一切都与约定有关,您也应该遵循它们。
您还想查看嵌套路由 https://guides.rubyonrails.org/routing.html#nested-resources
对于销毁动作,您通常不需要嵌套路线,因为有了游戏的 ID,您应该能够在数据库中找到它并销毁它。您还设计了可以使用您已经使用的 current_user
的方法。
所以你可以有这样的路线:
resources :games, only: :destroy
然后使用link_to方法
<%= link_to 'Remove from library', game_path(game.id), method: :delete %>
如果连接是 LibraryGame
(因为它有一个 library_id
和一个 game_id
)那么这个
resource :user, only: [] do
resources :games, only: [:create, :destroy]
end
需要
resources :users, only: [] do
resources :library_games, only: [:create, :destroy], shallow: true
end
shallow: true
为您提供了用于索引、创建和新建的路由,如 users/1/library_games/x
,但用于显示、编辑、更新和销毁的路由,如 library_games/x
。两全其美。
然后你的 link 将是 <%= link_to "Remove from Library", library_game_path(library_game), method: :delete %>
。