Rails trucs rapides #5

No Comments

Comment créer un fichier de log qui s’appelle autrement que ENV.log

Simple,

Dans le fichier environnement de votre choix entrer simplement cette ligne:

config.logger = Logger.new(RAILS_ROOT+'/log/NOM-DE-VOTRE-CHOIX.log')

Pour plus de possibilité de configuration voir cet excellent article

Bookmark and Share

Rails trucs rapides #4

No Comments

Aujourd’hui, un petit truc simple que Benoit Goyette m’a montré, la méthode count() d’ActiveRecords

J’utilisais jusqu’ici la requête suivante Model.find_by_sql(“SELECT COUNT(column_name) FROM table WHERE= conditions”)

J’étais convaincu que cette méthode simple et directe était la méthode la plus rapide et propre pour faire un count eh bien non bien que cette méthode fonctionne, la fonction count de ActiveRecords est très similaires à celle-ci.

Démonstration:

p=Post.find_by_sql(“SELECT COUNT(*) FROM posts”)
SELECT COUNT(*) FROM posts en 1.4 ms (affichage console)

p=Post.count
SELECT count(*) AS count_all FROM "posts" en 1.4 ms (affichage console)

Bon, je pensais que ma méthode SQL était plus vite que celle d’ActiveRecords, j’crois bien que je me suis trompé!

Les avantages d’utilisé la méthode activeRecords count, c’est que l’on peut utiliser tous les arguments habituels, :conditions, :joins, :group, :from, :select, etc…. et puis en plus, c’est beaucoup plus court à écrire et on aime ça!

Dans le même ordre d’idée, on peut également se servir de la fonction Model.maximum(‘column’)

Exemple:

Post.maximum(‘count_votes’)
SELECT max("posts".count_votes) AS max_count_votes FROM "posts"

va nous retourner le maximum de votes enregistrer sur tous les posts!

Dans cette lignée on retrouve les fonctions Model.minimum, Model.average et Model.sum
Référence

Bookmark and Share

Rails trucs rapides #3

No Comments

Au menu aujourd’hui, le “eager loading” via ActiveRecords.

Je vous avais promis de vous parler prochainement du paramètre :include, voici donc ce à quoi il sert!

Imaginez-vous un blogue contenant plusieurs Posts ayant plusieurs commentaires associé à plusieurs auteurs (exemple classique retaçable sur le web).

À prime abord, on pense immédiatement à faire cela :

@post = Post.find(id)

Par la suite on veut tous les commentaires associés à ce post alors on écrit:

@comments = Comment.all(:select => ‘comment.id, comment.author_id , comment.body’, :conditions => ['comments.post_id = ?', post_id ]

Ensuite pour afficher chaque nom d’auteur sur chaque commentaire on peut faire une opération de ce type

@comments.each do | comment |
puts comment.author.name
end

Pour chaque commentaire une requête sera généré pur aller chercher le nom de l’auteur… Si aucune :limit n’est imposé et qu’il y a plusieurs centaines de commentaires, tout cela peut devenir rapidement malsain et lent.

Il y a plusieurs façon d’approcher le problème bien que je ne prenne pas position ici sur la meilleur façon de procéder. À chaque projet son contexte.

Le “eager loading” nous permet de faire une seule requête pour les charger, le post, les commentaires et l’auteur avec l’utilisation de :include

Nous aurions donc une requête comme celle-ci:

@post = Post.find(:conditions => ['posts.id = ?', post_id ], :include => [:comments, :author] )

Cette requête me retourne tous les commentaires et auteurs associés à ce post d’un seul coup au lieu de faire plusieurs dizaine de requête.

Cette manière de faire peut s’avérer coûteuse au niveau de la base de donnée. J’aurais tendance à essayer de faire des benchmarks ou de regarder le output que Rails donne dans la console afin de voir qu’elles sont les points faibles de l’application afin de l’améliorer. De plus, nous sommes depuis quelques temps abonnés au service de monitoring New Relic. Ce service nous permet d’observer visuellement les endroits ou les performances de nos applications laissent à désirer.

En gardant cela en tête, il sera plus simple d’optimiser le projet lors des dernières phases.

Référence => Eager loading of associations

Bookmark and Share

Rails trucs rapides #2

No Comments

Rails est synonyme de raccourcit, il nous permet par exemple de faire une simple requête DB en une ligne comme ceci:

Model.find(id) ou encore Model.all, Model.first, Model.last
Model.all va générer une requête semblable à cela SELECT * FROM model

Simple non!?
Très! Oui, mais….. Cette requête retourne et met en mémoire toutes les données de la row. A-t-on réellemement besoin de retourner toutes les colonnes?

Il est plus long lors d’une requête de retourner toutes les colonnes que de n’en retourner seulement quelques unes. Bien sur on parle ici de millisecondes, mais sur certains sites, ces millisecondes peuvent s’avérer être précieuse.

Si on veut construire un select plus précis et moins “time consumming” on peut le faire avec la même fonction dans Rails, il suffit de lui passer un seul paramètre comme ceci.

Model.all(:select => ‘model.id, model.firstname, model.lastname’)
génère ceci => SELECT model.id, model.name, model.lastname FROM Model

Cette manière de faire, bien que plus longue à écrire, est à mon avis une bonne pratique à appliquer sur le web. Pourquoi charger des données non utilisées dans un objet alors que nous n’avons besoin que de quelques colonnes!? Je n’en vois pas la raison.

En plus du pratique argument :select, il est possible de passer plusieurs autres d’arguments à la méthode find. En voici une liste:

: order, :from, :conditions, :joins, :group, :limit, : offset, :readonly, :lock et :include.

référence => Railsbrain

Bookmark and Share

Older Entries