我的API后端有三个模型 - User
,Game
和Ownership
,它们充当用户和游戏之间的连接表。
我有一个调用远程API的服务方法来获取用户拥有的游戏数据。然后,它使用数据将相关游戏添加到数据库中,并使用额外数据(game_count)更新用户,并创建用户与其游戏之间的关系。我能够做到这一点:
class GameService
def self.getGamesForUser(user)
# response hash gets populated here
games = response[:games].map do |data|
Game.find_or_create_by(app_id: data[:appid]) do |g|
g.name = data[:name]
g.icon = data[:img_icon_url]
g.logo = data[:img_logo_url]
end
end
user.update games: games, game_count: response[:game_count]
end
end
到目前为止,这么好。在更新用户时,会自动创建用户和游戏之间的所有权关联。但我还想在连接表中同时添加额外的属性(如播放时间)。我一直无法找到一个很好的解决方案。我尝试通过向游戏模型添加nested_attributes_for
并调用
accepts_nested_attributes_for :ownerships
g.ownerships_attributes = [{
playtime: data[:playtime_forever]
}]
在更新用户之前,但似乎没有任何效果。我觉得必须有一个优雅的解决方案,我只是没有看到它。
以下是我的模型的代码:
class User < ApplicationRecord
has_many :ownerships
has_many :games, through: :ownerships
end
class Game < ApplicationRecord
has_many :ownerships
has_many :owners, through: :ownerships, source: :user
end
class Ownership < ApplicationRecord
belongs_to :user
belongs_to :game
end
答案 0 :(得分:0)
在迭代游戏时,将游戏时间保存在哈希中(将game.id作为键)
games = response[:games].map do |data|
playtimes = Hash.new
game = Game.find_or_create_by(app_id: data[:appid]) do |g|
g.name = data[:name]
g.icon = data[:img_icon_url]
g.logo = data[:img_logo_url]
end
#This is outside the find_or_create_by because it must be done for all games, not just the newly created.
playtimes[game.id] = data[:playtime_forever]
end
Finnaly,在更新游戏后,更新联接表中的游戏时间:
user.ownerships.find_each do |own|
own.update_attributes(:playtime => playtimes[:own.game_id])
end