On 7/2/07, Jean-François Trân <[EMAIL PROTECTED]> wrote:
>
>
> Le 02/07/07, renaud morvan<[EMAIL PROTECTED]> a écrit :
> > > Tu peux utiliser la méthode paginate_collection définie ici :
> > >
> > > http://snippets.dzone.com/posts/show/389
> > >
> > > ce qui te permet d'écrire :
> > >
> > > @ville = Ville.find :first,
> > > :include => :hotels,
> > > :conditions => [ 'name = ?' , 'Paris' ]
> > >
> > > @hotels_pages, @hotels = paginate_collection @ville.hotels,
> > > :per_page => 10,
> > > :page => params[:page]
> >
> > Nan très très mauvaise perf ici, cette technique est à éviter
> > IMHO, ca charge toute la collection en mémoire à chaque
> > pagination donc ca tuera n'importe quel serveur dès qu'on a une
> > grosse collection (Paris m'a tué ?).
>
> L'OP voulait utiliser #paginate, càd le système de pagination
> inclus dans Rails ; #paginate_collection n'est ni meilleur, ni
> plus mauvais, puisqu'il utilise exactement la même technique.
> Si on n'est pas gêné par les inconvénients de #paginate concernant
> les performances, on ne le sera pas avec #paginate_collection.
Je m'en veux d'insister mais il me semble que ce n'est pas tout à fait
exact.
@ville.hotels chargera (ou a chargé dans ton exemple à cause de l'include)
tous les hotels en mémoire. Ensuite c'est une pagination ruby, donc
absoluement pas scalable ou rapide si on a beaucoup d'hotel.
@hotels_pages, @hotels = paginate :hotels, :per_page => 10, :page =>
params[:page], :conditions => {:page_id => params[:id]}
(on évite les joins ca ne sert à rien ici, mieux vaut préfetché ville au
besoin avec un simple select ultra performance si la table est bien indexée,
ca permet en plus dans le futur d'avoir une factory sur ville si ca devient
un bottleneck).
Ce paginate devrait générer deux requetes, un count(*) et un select avec
offset et limit, et ne charger en mémoire que les 10 hotel nécessaire.
Si on rajoute les joins il faut une requête supplémentaire car il est
impossible d'utiliser simplement le offset + limit en cas de jointure (rails
gère ca tout seul) mais même dans ce cas là ca reste du pur mysql et ca ne
générère pas d'objet active record en trop, juste les 10 nécessaire.
De plus, ce n'est pas pour rien que j'ai rajouté : "Il est intéressant
> aussi de regarder les autres systèmes de pagination
> (paginating_find, will_paginate...)"
Et tu as raison mais à mon avis mieux vaut ne pas se précipiter, un seul
survivra à rails 2.0 et mieux vaut attendre pour choisir le bon et se
contenter de solution légère en attendant du type
http://weblog.jamisbuck.org/2007/4/6/faking-cursors-in-activerecord. :)
Ce sont les helpers ActionView de pagination qui sont très mauvais dans
rails, mais coté controller paginate est plutôt satisfaisant et fait
parfaitement le boulot tant qu'on ne fait pas de conditions sur les joins.
Ce qu'apporte ces plugins et que n'a pas rails c'est une pagination
directement coté model avec un vrai système pour récupérer l'ensemble des
entrées par paquet au lieu de tout récupérer d'un coup avec un find :all. Ce
qui est typiquement indispensable pour faire une fonction d'export qui
tienne la route si on a plus de 1000 entrées dans la base de donnée.
Renaud
--~--~---------~--~----~------------~-------~--~----~
Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de
Google Groups.
Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse
[email protected]
Pour résilier votre abonnement envoyez un e-mail à l'adresse [EMAIL PROTECTED]
-~----------~----~----~----~------~----~------~--~---