0

ユーザーは、お気に入りを通じて多くのトラックを持っています。: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

user.rb

def favorites_as_public_tracks
  favorites.joins(:track).sort_by(&:created_at).map(&:as_public_track)
end

お気に入り.rb

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

track.rb

  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

何百もの SELECT トラック where track.id='...' クエリを作成せずにこれを行うにはどうすればよいですか?

ありがとう!

4

1 に答える 1

0

すべてのインスタンスで同じリストがある場合は、それをインスタンス メソッドではなくクラス メソッドにすることを検討してください。パブリック属性とプライベート属性のリストをクラス メソッドとして作成できるかどうかを確認してください。それ以外の場合、インスタンスごとにこれらのリストを作成すると、レコードごとにヒットが得られます。

通常、:include :trackss でfind修正できますが、ここでは問題ではないと思います。

幸運を!

于 2012-06-15T03:50:11.453 に答える