【问题标题】:Destroy method: Passing params for API gathered data销毁方法:为 API 收集的数据传递参数
【发布时间】:2021-03-09 21:39:21
【问题描述】:

我正在开发一个应用程序,用户可以在其中搜索游戏(从 API 提取的数据),并将它们添加到库中。我设法让添加部分正常工作,但我在从用户库中删除游戏时遇到了一些问题。

这是我的创建和销毁函数。

  def create
    @library_game = Game.new
    @library_game.game_id = params[:game_id]
    @library_game.fetch_data
    @library_game.save!
    current_user.build_library
    current_user.library.games << @library_game
    redirect_to library_path
  end

  def destroy

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

使用当前代码,当我尝试删除某些内容时,我收到以下错误: GamesController#destroy 中的 ActiveRecord::AssociationTypeMismatch Game(#70255379902700) 预期,得到 {:game=>"52921"} 这是 Hash(#70255376633020) 的一个实例

所以它似乎正在获取 id 但它正在期待整个游戏?我尝试编辑我的参数以仅包含 :game 或 :game_id 但我仍然收到错误。

这里是删除游戏的链接。

<%= link_to 'Remove from Library', user_game_path(game.id), method: :delete %>

这是我展示关联的模型。

游戏

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

图书馆

class Library < ApplicationRecord
  belongs_to :user
  has_many :library_games
  has_many :games, through: :library_games
end

用户

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  has_one :library
  has_many :games, through: :library

  def has_game?(game)
    games.where(id: game.id).exist?
  end

  def build_library
    return if library.present?
    self.library = Library.new
  end
end

图书馆_游戏

class LibraryGame < ApplicationRecord
  belongs_to :library
  belongs_to :game
  has_one :user, through: :library
end

我的销毁方法出了什么问题?

【问题讨论】:

  • 应该是current_user.games.where(game_id: params[:id]).destroy
  • 我相信我之前尝试过。我再次尝试以确保我得到错误数量的参数(给定 0,预期为 1)作为错误。
  • 啊,抱歉,应该是destroy_all,因为它正在获取结果集
  • 我试过了,在 GamesController#destroy 中得到 ActiveRecord::StatementInvalid, PG::UndefinedColumn: ERROR: column games.game_id does not exist LINE 1: ...raries"."id" WHERE "库"."user_id" = $1 AND "games"."g... ^.也将其更改为 current_user.library.games.where(game_id: params[:id]).destroy_all 但得到相同的错误

标签: ruby-on-rails api destroy


【解决方案1】:

这是我对您的领域模型的理解,

Users (1 to 1)-> Library (1 to n)-> Library Games (1 to 1)-> Games

如果这种理解是正确的,那么我发现您的创建和销毁方法存在问题。您应该创建和销毁LibraryGames 的实例,而不是Games。以下是您如何实现事物的粗略想法,

  def create
    # current_user.build_library # Wouldn't all your users already have libraries?
    @library_game = LibraryGame.new
    @library_game.game_id = params[:game_id]
    @library_game.library = current_user.library
    # @library_game.fetch_data # What does this do? This might not be needed here
    @library_game.save!
    redirect_to library_path
  end

  def destroy
    current_user.library_games.destroy(params[:id])
    redirect_to library_path
  end

【讨论】:

  • 我得到验证失败:游戏必须存在于@library_game.save!使用这种方法。我已经可以使用我当前的创建方法将游戏添加到库中,因此我认为不需要完全重新调整它。我还在销毁中为 library_games 获得了未定义的方法。 fetch_data 从 API 获取数据(此处的文档:github.com/games-directory/api-giantbomb
  • 我不确定您发送给create 请求的参数是什么。您应该在 create 方法中创建 LibraryGame 而不是 Game 的原因是,如果两个用户将相同的游戏添加到他们的库中,那么您应该在数据库中创建游戏的单个实例,但是两个LibraryGame 的实例。也许我弄错了,但据我了解,您的 create 方法似乎存在缺陷。
  • 那么我应该给我的 library_game 模型提供与我的游戏模型类似的方法并包含 attr_accessor: 数据吗? LibraryGame.new 需要是我从 API 中提取的数据的一个实例。也许这不是最优雅的解决方案,但我当前的创建方法正在工作,所以我想创建一个销毁方法以适应我已有的方法。必须将大量 API 数据复制到 LibraryGame 模型似乎是多余的。
猜你喜欢
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-07
相关资源
最近更新 更多