2010-05-07 11 views
16

Używam will_paginate dla stronicowania, który działa dobrze do tej pory, z wyjątkiem tej jednej rzeczy.będzie _paginate with named_scopes

Gdy próbuję paginate zakres, na przykład

class User < ActiveRecord::Base 

    named_scope :scope, lambda { etc } 

end 

User.scope.paginate({:page => params[:page], :per_page => 10}) 

który powie mi paginate jest metoda niezdefiniowany. Wolałbym nie używać drugiego rozwiązania tylko dla tego zakresu, czy jest coś, co mogę tutaj zrobić?

Odpowiedz

9

Lowgain, wersja klew powinna działać po wyjęciu z pudełka. W swojej wersji powinieneś napisać:

User.scope.paginate :page => params[:page], :per_page => 10 

Preferuję inne podejście do stronicowania. Pozwala, aby kontroler bardziej czyste i obudowuje paginacji na poziomie modelu, bo np

class Property < ActiveRecord::Base 
    named_scope :all_properties, lambda {{ :order => "name asc" }} 

    def self.admin_properties(page = 1) 
    self.all_properties.paginate(:page => page, :per_page => Settings.admin.per_page) 
    end 
end 

A w kontrolerze całkiem jasne kodu:

class Admin::PropertiesController < Admin::AdminController 
    def index 
    @properties = Property.admin_properties(params[:page]) 
    end 
end 

ps: Settings.admin.per_page - to to ustawienia Searchlogic.

+0

Hmm, to jest interesujące! Czy istnieje jakaś zauważalna wadliwość działania, ponieważ robi to w paginacji każdej własności? – Lowgain

+0

W jaki sposób można go paginować każdą nieruchomość? :) Nie każdy, ale wszystko. Nazwany zakres * all_properties * jest rodzajem metody klasy (nie instancji!). Tak więc, gdy wywołujemy * self.all_properties *, otrzymujemy wszystkie właściwości z tego nazwanego zakresu. Potem je paginujemy. Własność oznacza klasę Właściwość samą w sobie - nie przedmiot klasy Właściwość. – Voldy

2

Mam named_scope zdefiniowane tak:

named_scope :look_for, lambda { |search| bla;bla;bla } 

nazywam go:

Person.look_for(params[:search]).paginate :page => params[:page] 

I to działa. Może potrzebujesz jakiegoś parametru do swojego zakresu?

+0

hmm, jakiego rodzaju parametru można się spodziewać? zakres wydaje się działać poza tym, że jest podzielony na strony – Lowgain

+0

Jeśli twój zakres ma parametr, powinieneś go podać. Jeśli nie, to nie;). Mój przykład dotyczy parametru. – klew

2

Trochę dziwne rozwiązanie, ale

User.scope.find(:all).paginate :page => params[:page], :per_page => 10 

prace?

1

Lowgain, to nie brzmi jak ty, ale po prostu, aby się upewnić - tak naprawdę nie robisz testów z named_scope o nazwie zakres prawda? Ponieważ zakres jest istniejącą metodą i używanie jej jako nazwy zasięgu powoduje błąd (i nieskończoną pętlę).

EDIT:

Czy Twój named_scope zdarzyć obejmują: klauzuli LIMIT? Właśnie zacząłem mieć podobny problem. Mam odpowiedź modelu który belongs_to Użytkownika, o nazwie zakres coś takiego:

named_scope :top, lambda { |limit| { 
      :limit => limit, 
      :order => 'total_score DESC' }} 

A ja widząc wyniki w konsoli, takie jak to:

?> u = User.find 1 
?> u.responses.length 
=> 9 
?> u.responses.paginate(:page => 1, :per_page => 5).length 
=> 5 
?> u.responses.top(3).length 
=> 3 
?> u.responses.top(3).paginate(:page => 1, :per_page => 5).length 
=> 5 

to! W jaki sposób moje 3 strony mogą się paginować, aby wytworzyć więcej niż 3 wiersze?Na swoim przykładzie starałem swoją find (: all) Sztuczka z podobnych wyników:

?> u.responses.top(3).find(:all).paginate(:page => 1, :per_page => 5).length 
=> 3 

To wygląda na błąd w named_scope, bo mogę wziąć will_paginate z obrazu i uzyskać podobny chaos występuje:

?> u.responses.top(3).length 
=> 3 
?> u.responses.top(3).size 
=> 9      <-- .size produces wrong answer 
?> r = u.responses.top(3) 
?> r.size 
=> 3      <-- correct when result assigned to var 

Do tej pory wydaje się, że dzieje się tak tylko wtedy, gdy używam MySQL. Myślę, że przeczytałem inny post na StackOverflow, w którym ktoś miał podobny problem z użyciem rozmiaru .size z wynikami AR i MySQL, a rozwiązaniem było zawsze użycie .length na swoich wynikach AR. Próbowałem modyfikować will_paginate, aby zastąpić wszystkie wystąpienia. Rozmiar z. Length, ale niestety nie było to takie proste, ale podejrzewam, że ten lub podobny problem w jakiś sposób wpływa na will_paginate.

Na razie używam twojej sztuczki find (: all) do zhakowania wokół tego.

+0

Właśnie zdałem sobie sprawę, że napisałem o tym samym blogu 2 miesiące temu, zapomniałem o tym, a następnie "odkryłem" to dzisiaj. Nienawidzę starzenia się! – MikeJ