2011-06-25 11 views
9

W dokumentacji zachłanne ładowanie jest powiedziane, że:Jak bardzo chcesz się ładować z limitami?


Jeśli chętny obciążenie skojarzenie z określonym: opcja limitu, zostanie zignorowany, wracając wszystkie związane z nimi obiekty:

class Picture < ActiveRecord::Base 
    has_many :most_recent_comments, :class_name => 'Comment', 
            :order => 'id DESC', :limit => 10 
end 

Picture.find (: first,: include =>: most_recent_comments) .most_recent_comments # => zwraca wszystkie powiązane komentarze.


Jeśli tak, to jaki jest najlepszy sposób osiągnięcia "limitu" załadunku?

Załóżmy, że chcemy załadować 10 ostatnich wpisów na blogu na pierwszej stronie bloga, ale nie chcemy ich wszystkich, więc czy należy określić limit i kolejność kolekcji?

Co dalej, czy można określić te same warunki dla elementów, które są głęboko załadowane - na przykład pokazują tylko trzy pierwsze komentarze na każdym blogu?

Blog.find(:blog_id, :include => {:posts => :comments }) 
+1

Spójrz na to odpowiedź ... http://stackoverflow.com/questions/9808674/rails-eager-load-and-limit – user1896290

Odpowiedz

0

Możesz użyć tej konstrukcji: Picture.find(:first, :include => :most_recent_comments).most_recent_comments.limit(10)

Zobacz więcej AR guide

+6

Wzór opisałeś nie ogranicza oryginalne zapytanie, tylko dane z niego zwrócone. Wyzwaniem jest ograniczenie pierwotnego zapytania tak, aby nie ładowało ** wszystkich ** postów z blogów do pamięci –

4

Wierzę, że to dlatego, że polecenie SQL LIMIT nie dobrze przekłada się na to, co staramy się robić. LIMIT ograniczy sumę wierszy zwróconych przez zapytanie. Jednak nie próbujesz tego zrobić. Próbujesz ograniczyć liczbę wierszy połączonych dla każdego zwróconego obrazu. Aby osiągnąć ten efekt, musisz użyć skomplikowanego kodu SQL, który może być trudny do zoptymalizowania, jeśli Twoje tabele są duże. W tym momencie zastanawiałbym się, dlaczego próbujesz ograniczyć załadowane wiersze.

Jeśli maksymalna liczba ładowanych komentarzy jest łatwa do zarządzania (< 2000), prawdopodobnie nie powinieneś martwić się ograniczaniem na końcu SQL.

Jeśli jednak ładujesz tylko 10 postów, uważam, że nie jest to w ogóle oczekiwane. Nie spodziewałbym się dodatkowych 10 zapytań, które spowolniłyby wiele rzeczy, ao której dodały czas, można nadrobić, próbując innych technik optymalizacji, takich jak buforowanie.

Powinieneś pozwolić, aby lunety wykonały dla ciebie brudną robotę, a nie prowokację. To promuje możliwość ponownego użycia, łatwość konserwacji, czytelność.Przykład:

Class Picture < ActiveRecord::Base 
    has_many :comments, :order => 'id DESC' do 
    def recent 
     limit(10) 
    end 
    end 
end 

ten sposób .comments jest tam, kiedy jest to potrzebne, a można również zakres ją tak:

@picture.comments.recent 
1

Użyłem will_paginate mi pomóc wraz z upragnieniem załadunku (using includes) jak mam załadować wiele związanych modele w jednym ujęciu bez użyciu limit

Image.includes(:user,:tags).where("user_id !=?",current_user.id).paginate(:page => params[:page], :per_page => 15) 

LUB (bez will_paginate (użyciulimit)

Image.includes(:user,:tags).where("user_id !=?",current_user.id).limit(30).order("created_at ASC") 

... dać mu try..hope to pomaga.

Powiązane problemy