2010-05-07 13 views
16

che sto usando will_paginate per l'impaginazione, che ha lavorato bene finora, tranne che per questa cosa.will_paginate con named_scopes

Se provo ad impaginare un ambito, per esempio

class User < ActiveRecord::Base 

    named_scope :scope, lambda { etc } 

end 

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

Che mi dirà impaginare è un metodo non definito. Preferirei non dover usare una seconda soluzione solo per questo scopo, c'è qualcosa che posso fare qui?

risposta

9

LowGain, la versione di klew dovrebbe funzionare out of the box. Nella vostra versione si dovrebbe scrivere:

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

preferisco un altro approccio per l'impaginazione. Permette di rendere più pulita e di controllo incapsula impaginazione a livello di modello, per esempio:

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 

E in un controller di codice abbastanza chiaro:

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

ps: Settings.admin.per_page - questo è Searchlogic impostazioni.

+0

Hmm, questo è interessante! Esiste qualche tipo di inconveniente prestazionale notevole nel farlo in questo modo, poiché impagina ogni proprietà? – Lowgain

+0

Come può impaginare ogni proprietà? :) Non tutti, ma tutti. L'ambito denominato * all_properties * è un tipo di metodo di classe (non di istanza!). Pertanto, quando chiamiamo * self.all_properties *, riceviamo tutte le proprietà da questo ambito denominato. Quindi li impaginiamo. Auto significa classe Proprietà stessa - non oggetto di classe Proprietà. – Voldy

2

Ho un named_scope definita in questo modo:

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

I chiamarlo:

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

e funziona. Forse hai bisogno di qualche parametro per il tuo scopo?

+0

hmm, che tipo di parametro ti aspetti? l'oscilloscopio sembra funzionare al di fuori dell'impaginazione – Lowgain

+0

Se il tuo scope assume parametri, dovresti dargliene uno. Se no, allora non farlo;). Il mio esempio è con parametro. – klew

2

Una specie di soluzione di strano, ma

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

opere?

1

Lowgain, non suona come sei, ma solo per essere sicuro - in realtà non stai facendo test con un named_scope chiamato scope giusto? Poiché lo scope è è un metodo esistente e l'utilizzo come nome dell'ambito causa un errore (e un ciclo infinito).

EDIT:

Il vostro named_scope capita di includere una: clausola di limite? Ho appena iniziato ad avere un problema simile. Ho una domanda al modello che belongs_to utente, con un qualcosa di ambito denominato in questo modo:

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

E sto vedendo risultati nella console di questo tipo:

?> 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 

Yikes! Come può la mia top 3 impaginare per produrre più di 3 righe?Per il tuo esempio ho cercato il tuo find (: all) ingannare con risultati simili:

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

Questo appare come un bug in named_scope, perché posso prendere will_paginate fuori dal quadro e ottenere caos simile a verificarsi:

?> 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 

Finora, questo sembra accadere solo quando sto usando MySQL. Penso di aver letto un altro post su StackOverflow in cui qualcuno ha avuto un problema simile usando .size con risultati AR e MySQL, e la soluzione era di usare sempre .length sui loro risultati AR. Ho provato a modificare will_paginate per sostituire tutte le istanze di .size con .length, ma purtroppo non era così semplice, ma ho il sospetto che questo o un problema simile abbia in qualche modo effetto su will_paginate.

Per il momento, sto usando il trucco find (: all) per aggirare questo.

+0

Mi sono appena reso conto che ho parlato di questa stessa cosa 2 mesi fa, l'ho dimenticato, l'ho "riscoperto" oggi. Odio diventare senile! – MikeJ

Problemi correlati