使用`where`语句查找关联计数的最佳语法是什么

时间:2012-12-12 20:34:19

标签: ruby-on-rails ruby activerecord

我可以想到几种方法来做到这一点,但我不确定该选择什么..

我有类Topic,我正在尝试对此范围进行调整,以便只有在关联对象Replytopic.replies作为大于0的计数时才返回主题。 / p>

最糟糕的做法是:

@topics.select{ | topic | topic.replies > 0 && topic.title == "Conversation" }

理想情况下,我想使用where范围。

  scope = current_user.topics
  scope = scope.joins 'left outer join users on topics.registration_id = registration_members.registration_id'
  # scope = .. here I want to exclude any of these topics that have both the title "Conversations" and replies that are not greater than 0

我需要将这些选择“附加”到已经选择的任何其他内容。所以我的选择不应该排除所有其他选择。它只是说任何回复小于1的Topic,也称为“对话”应该从最终回报中排除。

有什么想法吗?

更新

一个半散的想法:

items_table = Arel::Table.new(scope)
unstarted_conversations = scope.select{|a| a.title == "Conversation" && a.replies.count > 0}.map(&:id)
scope.where(items_table[:id].not_in unstarted_conversations)

1 个答案:

答案 0 :(得分:1)

您可以使用名为 计数缓存 的内容,基本上它所做的是向表中添加字段并在该字段中存储指定的“关联”总数输入并自动更新。

查看旧屏幕/ ascii cast:http://railscasts.com/episodes/23-counter-cache-column?view=asciicast

以下是更新的内容:http://hiteshrawal.blogspot.com/2011/12/rails-counter-cache.html

在您的情况下将如下:

# migration
class AddCounterCacheToTopìc < ActiveRecord::Migration
  def self.up
    add_column :topics, :replies_count, :integer, :default => 0
  end

  def self.down
    remove_column :topics, :replies_count
  end
end

# model
class Replay < ActiveRecord::Base
  belongs_to :topic, :counter_cache => true
end

希望对你有所帮助。