2009-07-24 11 views
13

Marzą ładowanie jest ładny z include przypisująSzyny chętne ładowanie zliczeń?

Post.find(:all, :include => :author) 

Zastanawiam się, czy można również chętnie liczy obciążenia, jak gdybym chciał uzyskać liczbę komentarzy dla każdego postu, bez ładowania wszystkich same komentarze?

Może coś

Post.find(:all, :include => [:author, "count(comments)") 

Przypuszczam, że mógłbym użyć kolumny count_cache. Ale zrobienie tego w całości byłoby naprawdę piękne, jeśli to możliwe.

Dodatkowe punkty bonusowe, jeśli ktoś może pokazać, jak nie tylko uzyskać liczbę, ale również wprowadzić pewne warunki, takie jak liczba tylko zatwierdzonych stanowisk.

+0

Zostało to później rozszerzone w tym pytaniu: http://stackoverflow.com/questions/4908878/how-do-i-get-rails-to-eager-load-counts Co jest ściśle związane z: http://stackoverflow.com/questions/2870521/how-will-activerelation-affect-rails-includes-s-apapabilities (tak to znalazłem). –

Odpowiedz

-6

Przynajmniej w MySQL, jest to szybsze wykonanie tych dwóch oddzielnych wywołań, ponieważ unikniesz sprzężenia. Wiem, że to nie jest odpowiedź na to pytanie, ale wydaje się, że próbujesz uzyskać lepszą szybkość i robi

Post.find ... 

Następnie

post.comments.count 

jest szybsze i bardziej wydajne pamięci (bazy danych) niż jeśli odzyskasz oba w jednym zapytaniu.

+4

Jednym z głównych powodów, dla których warto załadować ładunki, jest unikanie zapytań N + 1. – MrTheWalrus

+3

To wywołuje zapytanie N + 1 i nie odpowiada na pytanie. – davidgoli

24

powinny one być już załadowany Użyj

post.comments.length 

miałem ten sam problem, ponieważ używałem .count

+2

Nie sądzę, że to jest to, czego szuka. Spowoduje to załadowanie wszystkich wpisów w powiązaniu komentarzy, a następnie policzenie ich. On chce używać SQL, by z niecierpliwością pobierać liczbę bez ładowania obiektów. (A przynajmniej tak to rozumiem). – Mike

+0

Masz rację Mike. –

+1

To było rozwiązanie, którego szukałem. Na stronie indeksu i postach, na których chciałbym powtórzyć kolekcję i wyświetlić liczbę komentarzy - dzięki temu unika się uruchamiania żądań liczenia w każdym cyklu (pod warunkiem, że komentarze zostały załadowane razem z postami). Dzięki :-) – Renra

2

Spróbuj:

Comment.count(:group => :post) 

Aby filtrować według warunków:

Comment.count(:group => :post, :conditions => {:approved => true }) 

Zwrócą hasze ze słupkami jako kluczami i liczbą komentarzy jako wartościami.

+0

Nie jest to dokładnie to, czego szukam. Tak, możesz to zrobić w oddzielnym telefonie podobnym do tego. Ale nie sądzę, że możesz zrobić to w stowarzyszeniu takim, jak chciałem. Prawdopodobnie trzeba użyć kolumny count_cache. –

3

Po opracowaniu odpowiedzi avaynshtok, poniższa technika powinna po prostu wykonać 2 wywołania bazy danych.

# ./app/controllers/posts_controller.rb 

def index 
    # First load the posts 
    @posts = Post.all 

    # Then you can load a hash of author counts grouped by post_id 
    # Rails 3 version: 
    @comment_counts = Comment.count(:group => :post_id) 
    # Rails 4 version: 
    # @comment_counts = Comment.group(:post_id).count 
end 

Następnie w widoku

<!-- ./app/views/posts/index.html.erb --> 

<% @posts.each do |post| %> 
    <!-- reference the count by the post.id --> 
    post_count: <%= @comment_counts[post.id] %> 
<% end %> 
0

po prostu wpadł na to wyzwanie i rozwiązano to w ten sposób:

def trainee_counts 
    @trainee_counts ||= Hash[Trainee.group(:klass_id).count] 
end 

    # where the count is needed 
    trainee_counts[klass_id].to_i 

jedno połączenie do bazy danych i nie ładuje stażystów.

Powiązane problemy