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')

这是我的应用程序的一个非常非常关键的性能部分,所以如果可以的话,我需要它在一个查询中运行。

编辑

顺便说一句,我不确定上面的 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 回答