2010-11-02 1 views
1

У меня есть следующие модели:Rails 3 ActiveRecord запроса, возвращающие все записи модели и включают в себя подсчет связанных записей в одном запросе

class Keyword < ActiveRecord::Base 
    has_many :tags 
    has_many :studies, :through => :tags 
end 

class Tag < ActiveRecord::Base 
    belongs_to :keyword 
    belongs_to :study 
end 

class Study < ActiveRecord::Base 
    has_many :tags 
    has_many :keywords, :through => :tags 
end 

хочу массив, содержащий все ключевые слова, и каждое ключевое слово, и количество исследований помеченного с этим ключевым словом, так что я могу сказать:

<ul> 
<% @keywords.each do |keyword| %> 
    <li><%= "(#{keyword.number_of_studies}) #{keyword.title}") %></li> 
<% end %> 
</ul> 

Я уверен, что это возможно, вопрос: как?

ответ

3

Вы можете использовать счетчик кеша. Это сохраняет целочисленное значение для родительского объекта с количеством детей. ActiveRecord отслеживает.

class Post < AR::Base 
    has_many :comments 
end 

class Comment < AR::Base 
    belongs_to :post, :counter_cache => true 
end 

@post.comments_count 

Если вы действительно должны использовать один запрос без кэша счетчика:

@post = Post.find(first, :select => 'posts.*, count(comments.id) as comments_count',:joins => 'left outer join comments on comments.post_id = posts.id', :group => 'posts.id') 
@post.comments_count #=> From join query. 

Как вы можете видеть, это становится уродливым быстро. Лучше придерживаться счетного кеша или делать два отдельных запроса.

@post = Post.find(:first) # SELECT FROM posts 
@post.comments.count  # SELECT COUNT(1) FROM comments WHERE post_id = ? 
+0

Хорошо, это определенно решает проблему. Я надеюсь на какой-то запрос AREL, хотя это даст мне счет как часть запроса, когда я получу все ключевые слова. Я дал вам голос. –

+0

Хорошо, я обновил свой ответ тем, что вы хотите. Я все еще придерживаюсь мнения, что вы должны либо использовать 'counter_cache', либо выполнять два запроса. Это делает ваш код намного чище и менее подвержен ошибкам. – Ariejan

+0

Спасибо за подробный ответ, я могу заключить синтаксис запроса Rails 3 AREL из того, что у вас есть, и что у вас есть именно то, что я ищу. –