2

トピックとプロジェクト モデルがあります。それらの間に多対多のお尻があります(HABTM 1)。

トピックのインデックス ページに、各トピックのプロジェクト数を表示したいと考えています。ので、私は持っています

@topics = Topic.all(:include => [:projects])

私のコントローラーでは、これまでのところとても良いです。問題は、プロジェクト モデルが非常に大きいため、クエリがまだ非常に遅いことです。

Topic Load (1.5ms)   SELECT * FROM "topics" 

Project Load (109.2ms)   SELECT "projects".*, t0.topic_id as the_parent_record_id FROM "projects" INNER JOIN "projects_topics" t0 ON "projects".id = t0.project_id WHERE (t0.topic_id IN (1,2,3,4,5,6,7,8,9,10,11)) 

* を選択せず​​に名前または ID だけを選択するように 2 番目のクエリを作成する方法はありますか? counter_cache は HABTM Ass でサポートされていないため、自分で実装したくありません...この 2 番目のクエリを高速化する方法はありますか?

プロジェクトオブジェクト全体をロードせずにカウントを取得するだけです...

前もって感謝します、

ニコラス・ホック・イサザ

4

2 に答える 2

4
  1. counter_cache は非常に簡単に実装できます
  2. habtm を double has_many に変換できます。つまり、プロジェクト モデルとトピック モデルの両方で has_many :projects_topics (および projects_topics の belongs_to) にしてから、counter_cache を使用するか、projects_topics でのみ熱心な読み込みを行います。
  3. :select => "count(projects_topics.id)", :group => "topics.id" を実行できますが、気になる場合、これは postgresql ではうまく機能しません...

2 番目のオプションが最適な IMO です。通常、habtm はまったく使用せず、double has_many のみを使用します :)

于 2010-01-29T18:13:09.703 に答える
0

Devenv の応答カウンター キャッシュを拡張することは、この種のシナリオで通常使用するものです。

API ドキュメントから:

increment_counter と decrement_counter を使用して、関連付けられたクラスに属するオブジェクトの数をキャッシュします。カウンタ キャッシュは、このクラスのオブジェクトが作成されると増加し、破棄されると減少します。これには、関連クラス (Post クラスなど) で #{table_name}_count (所属する Comment クラスの comments_count など) という名前の列を使用する必要があります。このオプションに true/false 値の代わりに列名を指定して、カスタム カウンター キャッシュ列を指定することもできます (例: :counter_cache => :my_custom_counter)。 注: カウンター キャッシュを指定すると、そのモデルの読み取り専用リストに追加されます。 attr_readonly を使用した属性。

これは、 counter_cacheの ryan batesのrailscastsからのスクリーン キャストです。

これは、私が半年前に尋ねた質問に対する回答です。解決策は、簡単に実装できる自作のカウンター キャッシュでした。

于 2010-01-30T18:15:39.840 に答える