用户有很多曲目,通过收藏夹。收藏夹有一些关于相关轨道的额外每用户元数据,整个事件使用自定义:as_public
散列方法作为json blob返回。
即使我使用JOIN访问相关对象,我也会进行数百次非常基本的SELECT track FROM tracks WHERE track.id='1'
查询。 我想优化此查找。
def show
@user = User.find(params[:id])
respond_to do |format|
format.html # index.html.erb
format.json { render json: @user.to_json(:methods => [:favorites_as_public_tracks]) }
end
end
def favorites_as_public_tracks
favorites.joins(:track).sort_by(&:created_at).map(&:as_public_track)
end
class Favorite < ActiveRecord::Base
belongs_to :user
belongs_to :track
#Grabs some stuff from Favorite, merging it with the public data from Track
def as_public_track
track.public_attributes.merge(public_attributes_for_merging_onto_track)
end
# This stuff gets added onto track.to_json and used by javascript
def public_attributes_for_merging_onto_track
return {
:favorite_id => id,
:from_service => from_service,
:favorited_at => created_at,
:collection_name => "#{collection_name}, #{from_service}"
}
end
def public_attributes
private_attrs = [:user_id]
attributes.reject {|key, val| private_attrs.include? key.to_sym }
end
end
def public_attributes
private_attrs = [] #[:id]
attributes.reject {|key, val| private_attrs.include? key.to_sym }
end
当我将用户的收藏夹作为公共曲目访问时运行的SQL是:
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", "1"]]
Favorite Load (7.8ms) SELECT "favorites".* FROM "favorites" INNER JOIN "tracks" ON "tracks"."id" = "favorites"."track_id" WHERE "favorites"."user_id" = 1 ORDER BY "favorites".created_at DESC
Track Load (1.3ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = 1 LIMIT 1
Track Load (0.5ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = 2 LIMIT 1
Track Load (0.3ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = 3 LIMIT 1
Track Load (0.3ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = 4 LIMIT 1
Track Load (0.5ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = 5 LIMIT 1
Track Load (0.2ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = 6 LIMIT 1
Track Load (0.2ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = 7 LIMIT 1
Track Load (0.2ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = 8 LIMIT 1
如何在不使用track.id ='...'查询数百条SELECT轨道的情况下执行此操作?
谢谢!
答案 0 :(得分:0)
如果所有实例的列表保持不变,请考虑将其设置为类方法而不是实例方法。看看是否可以将公共属性和私有属性列表作为类方法。否则,要为每个实例构建这些列表,您将获得每条记录的命中。
通常:include :tracks
中的find
可以修复它,但我认为这不是问题所在。