0

where句の下にある関連モデルの数によってモデルのスコープを設定する必要があるプロジェクトに取り組んでいます。これは私が思いつくことができる最高のものです:

Subscription.where('message_cap > ?', TextMessage.where('created_at > ?', DateTime.now.beginning_of_month).where(subscription: subscription).count)

ただし、サブスクリプションが定義されていないため、機能しません。Railsクエリで、現在postgresにヒットしているモデルを参照できる方法はありますか? これが私が探しているSQLだと思います:

SELECT * FROM 'subscriptions' WHERE 'subscription.message_cap' > (SELECT COUNT(*) FROM 'text_messages' WHERE 'text_messages.subscription_id' = 'subscription.id' AND 'text_message.created_at > BEGINNINGOFMONTH')

これは私のアプリケーションのパフォーマンスにとって非常に重要な部分なので、できれば 1 つのクエリで実行する必要があります。

編集

ところで、上記の SQL クエリが有効かどうかはわかりません。私が探していたもののアイデアを伝えるためにそこに置いただけです。

4

2 に答える 2

1

以下を試してください。

Subscription.select('subscriptions.id').
  joins(:text_messages).
  where('messages.created_at > ?', date).
  group('subscriptions.id').
  having('COUNT(*) > subscriptions.message_cap')

クエリdateのパラメーターであること。

Subscription結果の各オブジェクトにはid、サブスクリプションののみが含まれることに注意してください。オブジェクト全体を取得するには、次のようなクエリが必要です。

Subscription.find(ids)

アプリケーションの重要な部分である場合は、お気に入りのテスト フレームワークを使用してクエリをテストする必要があります。

于 2014-05-02T14:16:51.773 に答える
0
query = "SELECT * FROM 'subscriptions' WHERE 'subscription.message_cap' > (SELECT COUNT(*) FROM 'text_messages' WHERE 'text_messages.subscription_id' = 'subscription.id' AND 'text_message.created_at > BEGINNINGOFMONTH')"
Subscription.find_by_sql(query)

それが十分に速くない場合は、サブスクリプションごとにテキスト メッセージ数をキャッシュすることを検討する必要があります。これは、ビューを作成するか、カウンター列をサブスクリプション テーブルに追加することで実行できます。ビューはより良い解決策ですが、実装にはより複雑です。

アップデート

subscriptions_table = Subscription.table_name
text_messages_table = TextMessage.table_name
foreign_key = TextMessage.reflect_on_association(:subscription).foreign_key
query = "SELECT * FROM '#{subscriptions_table}' WHERE '#{subscriptions_table}.message_cap' > (SELECT COUNT(*) FROM '#{text_messages_table}' WHERE '#{text_messages_table}.#{foreign_key}' = '#{subscriptions_table}.id' AND '#{text_messages_table}.created_at > #{Date.current.beginning_of_month}')"
Subscription.find_by_sql(query)
于 2014-05-02T14:17:00.677 に答える