Sql 查询多对多关联
我的项目中有3个模型:用户、游戏、游戏访问Sql 查询多对多关联,sql,ruby-on-rails,json,angularjs,has-and-belongs-to-many,Sql,Ruby On Rails,Json,Angularjs,Has And Belongs To Many,我的项目中有3个模型:用户、游戏、游戏访问 class User < ActiveRecord::Base has_many :game_visits has_many :games, through: :game_visits end class Game < ActiveRecord::Base has_many :game_visits has_many :users, through: :game_visits end class GameVisit &l
class User < ActiveRecord::Base
has_many :game_visits
has_many :games, through: :game_visits
end
class Game < ActiveRecord::Base
has_many :game_visits
has_many :users, through: :game_visits
end
class GameVisit < ActiveRecord::Base
self.table_name = :users_games
enum status: [:visited, :not_visited, :unknown]
belongs_to :user
belongs_to :game
end
如何优化它?您的
用户。game\u访问。按game\u id(game.id)
查找是触发所有这些查询的原因。您可以使用快速加载来解决此问题
将用户的分配更改为以下内容:
users = self.users.includes(:game_visits)
然后将users\u array
中的status
的赋值更改为:
status: user.game_visits.find{ |gv| gv.game_id == game.id }
上面的行使用的是可枚举的find
,而不是ActiveRelation。如果您坚持使用AR的find\u by\u game\u id
或其他find
,它仍然会触发查询
另一个优化方法是为游戏访问创建一个哈希,这样您就可以到处查找来执行如下操作:
user_game_visits_hash = \
user.game_visits.each_with_object({}) do |gv, hash|
hash[gv.game_id] = gv
end
# more code here
status: user_game_visits_hash[game.id]
还有一个小问题:如果方法参数中的game\u id
为零,那么方法的前两行将不必要地触发两个查询,因为您从游戏中提取所有id只是为了获取所有游戏。您可以将其更改为:
games = game_ids ? Game.find(game_ids) : Game.all
user_game_visits_hash = \
user.game_visits.each_with_object({}) do |gv, hash|
hash[gv.game_id] = gv
end
# more code here
status: user_game_visits_hash[game.id]
games = game_ids ? Game.find(game_ids) : Game.all