18-10-2009, 03:23 PM
Ça fait les requêtes de manière plus intelligentes. Cela dit, il faut que le développeur soit malin.
Admettons qu'on ai ce modèle, tout simple :
Ça dit quoi ?
Dans le contrôleur :
Là aussi, c'est simple : on sélectionne les posts publiés en paginant. On indique que le paramètre d'URL qui indique la page parcourue se nomme "page". On met tout ça dans une variable d'instance (comme l'indique le @) @posts, qui sera donc accessible dans la vue.
Dans la vue :
Le problème, c'est que Rails va lancer une requête pour chaque post, puisqu'à chaque itération, on va lui demander de compter les commentaires ! On va donc avoir un total de (nombre de posts + 1) requête !
Pour n'avoir que 2 requêtes (une pour récupérer les posts et une autre pour les commentaires de ces posts), on va modifier un peu le contrôleur :
Et voilà !
Et les ORM pour les autres langages, je suppose qu'elles sont bonnes, mais je ne les ai jamais utilisé "sérieusement" donc je ne peux pas me prononcer à leur sujet.
Ce que j'aime dans ActiveRecord, c'est son intégration avec Rails, la création très simple de liens, la génération éléments HTML avec les attributs class et id qui vont bien, etc.
Sephi-Chan
Admettons qu'on ai ce modèle, tout simple :
# Dans le modèle :
class Post < ActiveRecord::Base
@@per_page = 20
cattr_reader :per_page
default_scope :order => 'created_at DESC'
named_scope :published,
:conditions => [ 'published = ?', true ]
has_many :comments
end
Ça dit quoi ?
- Que quand on va paginer, ça va mettre 20 enregistrements par page (c'est une limitation propre au modèle, donc on met ce chiffre en tant que variable de classe. On génère ensuite un accesseur (au niveau de la classe) en lecture pour cette variable ;
- On dit que par défaut, à chaque fois qu'on récupérera des posts, ils seront triés par date de création ;
- On génère une scope qui nous permettra de filtrer nos posts. En faisant Post.published.all, on aura tous les posts publiés ;
- On dit qu'un post peut avoir plusieurs commentaires.
Dans le contrôleur :
class PostsController < ApplicationController
def index
@posts = Post.published.paginate(:page => param[:page])
end
end
Là aussi, c'est simple : on sélectionne les posts publiés en paginant. On indique que le paramètre d'URL qui indique la page parcourue se nomme "page". On met tout ça dans une variable d'instance (comme l'indique le @) @posts, qui sera donc accessible dans la vue.
Dans la vue :
<div id="posts">
<% for post in @posts %>
<% content_tag_for(:div, post) do %>
<h2><%= h(post.title) %></h2>
<div class="comments_count">
<%= link_to pluralize(post.comments.count, 'commentaire'),
post_path(post, :anchor => 'comments')
%>
</div>
<div class="content">
<%= simple_format(h(post.content)) %>
</div>
<% end %>
<% end %>
</div>
<%= will_paginate(@posts) %>
- Pour chaque post, on crée un bloc div le content_tag_for sert à générer un div qui devine la classe et l'identifiant du bloc. Ainsi, ici ce sera quelque chose comme <div class="post" id="post-23">...</div> ;
- On affiche le nombre de commentaires (mis au pluriel si besoin) en tant que lien pour afficher le détail de l'annonce avec une ancre pour aller vers les commentaires en bas ;
- On échappe les contenus avec le helper h() (un alias de html_escape()) ;
- On affiche si besoin les liens de pagination ;
Le problème, c'est que Rails va lancer une requête pour chaque post, puisqu'à chaque itération, on va lui demander de compter les commentaires ! On va donc avoir un total de (nombre de posts + 1) requête !
Pour n'avoir que 2 requêtes (une pour récupérer les posts et une autre pour les commentaires de ces posts), on va modifier un peu le contrôleur :
class PostsController < ApplicationController
def index
@posts = Post.published.paginate(:page => param[:page], :include => :comments)
end
end
Et voilà !
Et les ORM pour les autres langages, je suppose qu'elles sont bonnes, mais je ne les ai jamais utilisé "sérieusement" donc je ne peux pas me prononcer à leur sujet.
Ce que j'aime dans ActiveRecord, c'est son intégration avec Rails, la création très simple de liens, la génération éléments HTML avec les attributs class et id qui vont bien, etc.
Sephi-Chan