Le Blog du Geek Joyeux

Plus moins vite tu codes, moins plus vite ça plante

Quick Tips

  • size doesn't COUNT

    Publié le 17 janvier 2012 à 10:00 - Quick Tips

    Requêtes N+1

    Lorsque vous développez avec Rails, vous devez bien sûr faire attention aux requêtes qui sont effectuées et surtout éviter les requêtes N+1.

    Les requêtes N+1 sont celles qui sont lancées pour chaque élément d’une liste.

    Prenons l’exemple suivant :

    # Dans le contrôleur

    @articles = Article.all
    # SELECT articles.* FROM articles

    # Dans la vue

    <% @articles.each do |article| %>
    ...
    Nombre de commentaires: <%= articles.comments.count %
    >

    # SELECT COUNT(*) FROM comments WHERE comments.article_id = XY
    ...
    <% end %>

    Pour chaque article listé, une requête va être lancée pour compter ses commentaires.

    Heureusement pour nous, Rails fournit, dans l’API d’ActiveRecord un moyen d’éviter ces requêtes N+1. Il s’agit de la méthode includes qui s’utilise comme ceci :

    @articles = Article.includes(:comments).all
    # SELECT articles.* FROM articles
    # SELECT comments.* FROM comments WHERE comments.article_id IN (1, 2, ..., 42)

    On peut donc voir ici que l’ensemble des commentaires est récupéré d’un seul coup. Cela nous permet d’accéder aux informations des commentaires d’un article sans requête supplémentaire.

    Size vs. Count

    Le souci c’est que ça ne règle pas notre problème de count. En effet, si nous faisons de nouveau appel à count, les requêtes seront tout de même effectuées !

    L’astuce est donc d’utiliser size plutôt que count sur l’attribut comments de nos articles, ce qui va simplement retourner la taille du tableau contenant les commentaires associés. Ces derniers étant déjà chargés, le compte est bon !

    # Dans le contrôleur

    @articles = Article.includes(:comments).all
    # SELECT articles.* FROM articles
    # SELECT comments.* FROM comments WHERE comments.article_id IN (1, 2, ..., 42)

    # Dans la vue

    <% @articles.each do |article| %>
    ...
    Nombre de commentaires: <%= articles.comments.size %
    >

    ...
    <% end %>
    Comments
  • Utiliser rvm avec cron

    Publié le 24 septembre 2011 à 00:00 - Quick Tips

    Il y a quelques temps, j’avais besoin de lancer un script ruby avec cron. Le souci, c’est que sur mon serveur, tout est à base de rvm. De fait, cron ne sait pas trouver ruby puisque rvm est chargé par mon fichier .bashrc.

    La petite astuce pour que ça marche, c’est de dire à cron de charger mon environnement pour ce script spécifiquement :

    0 * * * * /bin/bash -l -c 'ruby mon_script.rb'

    En clair, l’option -l permet de charger l’environnement bash et l’option -c indique la commande à exécuter.

    Comments
  • Rendre git-diff plus précis

    Publié le 19 septembre 2011 à 00:00 - Quick Tips

    Git permet d’afficher différentes informations en couleur. Cela se fait dans le fichier de configuration, ~/.gitconfig.

    [color]
    ui = true

    Une des commandes concernées est git-diff. Cette coloration est bien pratique mais peut avoir ses limites. En effet, lorsque la différence sur une ligne se joue à quelques caractères seulement, il peut être difficile de détecter les modifications.

      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    - quis nostrud exercitation ullamco labaris nisi ut aliquip ex ea commodo
    + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
    non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    Une petite astuce pour les voir plus précisément est l’utilisation de l’option –word-diff

    git diff --word-diff=color

    Voici le résultat obtenu :

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboaris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
    non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    L’option prend différentes valeurs qui peuvent être utiles selon les circonstances.

    Comments
  • Gestion du PATH sous OS X

    Publié le 08 août 2011 à 00:00 - Quick Tips

    Une fonctionnalité bien pratique de OSX_ est la gestion du PATH. En effet un mécanisme permet de ne pas surcharger son .bashrc chaque fois que l’on doit rajouter une entrée dans le PATH.

    La magie s’opère dans le fichier /etc/paths et dans le dossier /etc/paths.d.

    Le premier est un listing des chemin généraux :

    /usr/bin
    /bin
    /usr/sbin
    /sbin

    Le deuxième est un dossier permettant d’ajouter des fichiers contenant des listings en plus. Ces fichiers seront chargés à la suite de /etc/paths.

    Exemple

    Si vous avez installé MySQL avec le DMG fourni sur le site officiel, vous pouvez ajouter le chemin des exécutables mysql en créant un fichier /etc/paths.d/mysql et y écrire la ligne suivante :

    /usr/local/mysql/bin

    Collision

    Si vous vous trouvez dans la situation où vous avez un exécutable dans un dossier non système et que vous souhaitez que ce dossier ait la priorité, mettez le en tête du fichier /etc/paths, les chemins sont chargés dans l’ordre.

    Comments
  • Éviter la création des fichiers ._ (point underscore) sous Mac OS X

    Publié le 30 janvier 2011 à 00:00 - Quick Tips

    Un comportement plutôt gênant sous OS X est la création des fichiers ._ (point underscore). C’est souvent un problème quand on veut créer une archive .tar.gz ou avec certains SCM.

    Voici une solution pour empêcher leur création.

    Dans votre .bashrc et votre .profile, ajoutez la ligne suivante :

    export COPYFILE_DISABLE=true
    Comments
  • Utiliser un shell non standard sous mac

    Publié le 28 décembre 2010 à 00:00 - Quick Tips

    Chaque fois que j’installe un shell sous Mac OS X et que je le règle par défaut gràce à chsh, l’application Terminal refuse de se lancer et me dit :

    Vous n’êtes pas autorisé à lancer cette application.
    L’administrateur a donné à votre shell une valeur illégale.

    Pour régler ce petit souci, il suffit d’ajouter le chemin vers votre shell dans le fichier /etc/shells :

    cat /etc/shells
    # List of acceptable shells for chpass(1).
    # Ftpd will not allow users to connect who are not using
    # one of these shells.

    /usr/local/bin/bash # bash installé avec homebrew
    /bin/bash
    /bin/csh
    /bin/ksh
    /bin/sh
    /bin/tcsh
    /bin/zsh

    C’est une erreur que l’on ne rencontre pas lorsque l’on utilise un terminal comme iTerm 2

    Comments
  • Utiliser la sortie d'une commande comme un fichier en shell

    Publié le 12 décembre 2010 à 15:00 - Quick Tips

    Il arrive qu’on ait besoin d’utiliser la sortie d’une commande comme si c’était un fichier. Voici une petite astuce pour ne pas passer par un fichier temporaire.

    diff <(ls /un/dossier/au/pif) <(ls /un/autre/dossier/au/pif)

    Et voilà avec cette syntaxe on a la différence entre deux dossiers sans utiliser de fichiers temporaires.

    Comments
  • Problème de police trop fine sous Snow Leopard

    Publié le 10 octobre 2010 à 00:00 - Quick Tips

    Il y a quelques jours j’ai réinstallé un Snow Leopard sur un Mac Mini.

    Lorsque j’ai lancé iTerm et TextMate, la police Monaco que j’utilise dans les deux n’était pas tout à fait comme d’habitude, plus fine et moins agréable.

    Cela vient d’un bug Snow Leopard qui ne reconnait pas toujours les LCD : il les voit comme des écrans CRT et désactive l’anti-aliasing sur les polices !

    Pour régler ce souci, tapez simplement ceci dans une console :

    defaults -currentHost write -globalDomain AppleFontSmoothing -int 2

    La prochaine fois que vous lancerez iTerm ou TextMate, ça devrait être bon.

    Comments
  • Travailler en case-sensitive sous Mac

    Publié le 25 juillet 2010 à 00:00 - Quick Tips

    HFS+, le système de fichiers utilisé par Mac OS X depuis un bout de temps déjà est, par défaut, case-insensitive. Il est toutefois possible, aujourd’hui, de choisir d’utiliser une version case-sensitive lorsque l’on installe OS X.

    La plupart du temps, ça n’est pas spécialement gênant. Quand il s’agit de travailler cela peut vite devenir handicapant.

    Lire la suite

    Comments
  • Désactiver la résolution interactive des conflits dans Subversion

    Publié le 10 juillet 2010 à 00:00 - Quick Tips

    Depuis la version 1.5 de Subversion, la résolution des conflits se fait de façon interactive lorsque l’on utilise svn update.

    svn update
    Conflict discovered in 'some/file/located/somewhere.rb'.
    Select: (p) postpone, (df) diff-full, (e) edit,
    (h) help for more options:

    Personnellement, je ne supporte pas ce nouveau mode. Je préfère de loin faire un update complet et corriger les conflits à posteriori.

    Pour le faire de manière ponctuelle l’option –non-interactive permet d’obtenir ce comportement.

    svn update --non-interactive

    Pour le faire de manière permanente, éditez votre ~/.subversion/config et ajoutez la ligne suivante dans la section miscellany :

    [miscellany]
    ...
    interactive-conflicts = no
    Comments
  • Surcharge de méthode élégante en Javascript

    Publié le 28 avril 2010 à 10:23 - Quick Tips

    Aujourd’hui, j’ai eu besoin de surcharger une méthode Javascript. Premier réflexe, réécrire la fonction en y ajoutant le code voulu.

    Soit le code qui suit :

    mon_objet.fait_le_café = function() {
    var tasse = prendre_une_tasse();
    tasse.verser_café();
    tasse.faire_chauffer();

    return tasse;
    }

    Afin d’ajouter du sucre, on pourrait surcharger de la façon suivante :

    mon_objet.fait_le_café = function() {
    var tasse = prendre_une_tasse();
    tasse.verser_café();
    tasse.faire_chauffer();

    tasse.ajouter_sucre();

    return tasse;
    }

    Jusque là, rien d’inhabituel. Mais quid du code propre, simple et surtout DRY ?

    Voici donc une façon plus élégante d’obtenir le même résultat en écrivant juste le code nécessaire :

    mon_objet.fait_le_café_sans_sucre = mon_objet.fait_le_café;

    mon_objet.fait_le_café = function() {
    var tasse = mon_objet.fait_le_café_sans_sucre();

    tasse.ajouter_sucre();

    return tasse;
    }

    C’est tout simple, ça fonctionne et c’est DRY

    Pour information, l’idée m’est venue du framework Ruby On Rails (en) et de sa méthode

    alias_method_chain (en)

    Comments
  • Rails - Utiliser SASS avec theme_support

    Publié le 09 mars 2010 à 22:47 - Quick Tips

    J’ai eu l’occasion de me prendre un petit moment la tête aujourd’hui sur comment utiliser des feuilles de styles SASS au sein de thèmes dans une application Rails.

    Pour la gestion des thèmes, j’ai utilisé theme_support qui permet de créer, pour chaque thème, un dossier ayant l’arborescence suivante :

    un_theme
    ├── images
    | └── preview.png
    ├── javascripts
    ├── stylesheets
    ├── views
    └── about.markdown

    Ce que je cherchais à faire était de pouvoir mettre des fichiers SASS dans le dossier stylesheets, mais que les CSS compilées soient placées dans <app_root>/public/stylesheets.

    Le plus simple moyen que j’ai trouvé pour faire ça, est d’ajouter le script suivant dans >app_root>/config/initializers/theme_sass.rb :

    # :template_location est normalement une String, on la convertie donc en Array
    Sass::Plugin.options[:template_location] = [[Sass::Plugin.options[:template_location], Sass::Plugin.options[:css_location]]]

    # Pour chaque thème, on ajoute son dossier stylesheets à la liste des sources SASS
    Theme.find_all.map(&:name).each do |theme|
    Sass::Plugin.options[:template_location] << ["#{RAILS_ROOT}/themes/#{theme}/stylesheets", Sass::Plugin.options[:css_location]]
    end
    Comments
  • Continuer d'ouvrir ses onglets en fin de liste sous Firefox 3.6

    Publié le 25 janvier 2010 à 13:43 - Quick Tips

    Depuis quelques jours maintenant, Firefox 3.6 est sorti. Cette nouvelle version apporte un certain nombre de nouveautés, dont certaines qui peuvent être déroutantes (<troll>le nouveau système de skins uselessfull par exemple ?</troll>).

    Bref ! Une nouveauté est l’ouverture des onglets relatifs (ouverture d’un lien de la page courante dans un onglet) à côté de l’onglet courant et non plus à la fin de la liste. Tout cela n’aurait rien de bien gênant si cette fonctionnalité pouvait être désactivée grâce à une simple case à cocher…

    Voici un moyen simple de revenir à l’ancien fonctionnement.

    Ouvrez l’URL about:config.

    Dans la zone de filtre saisissez insertRelated cela devrait laisser seulement une entrée :

    Firefox 3.6 about:config - insertRelatedTabsAfterCurrent

    Double-cliquez dessus pour passer sa valeur à false.

    C’est tout. Les nouveaux onglets devraient s’ouvrir maintenant en fin de liste.

    EDIT: Je viens de trouver un lien avec quelques astuces supplémentaires

    Comments
  • Deverouiller un groupe de fichiers sous Mac

    Publié le 28 décembre 2009 à 15:01 - Quick Tips

    Dernièrement, lors de la copie de fichiers depuis le disque dur d’une amie, je me suis retrouvé avec de nombreux fichiers verrouillés. Verrouillés au sens OS X du terme.

    Il est possible pour chaque fichier d’afficher ses infos et de décocher la case de verrouillage.

    Mais lorsque cela concerne une centaine, ou un millier de fichiers, d’un coup, cocher une simple case peut devenir quelque peu fastidieux.

    Pour effectuer cette action en ligne de commande, il suffit d’utiliser la ligne suivante :

    chflags nouchg <fichiers>
    Comments
  • Utiliser Paperclip avec Rails sous Mac

    Publié le 28 décembre 2009 à 14:48 - Quick Tips

    Pour gérer l’upload de fichiers dans les applications Rails, un plugin fréquemment utilisé est Paperclip. Récemment, lors du développement d’un projet, je me suis retrouvé confronté à un problème lors de l’envoie des fichiers. En effet, ça ne fonctionnait pas et je recevais un message d’erreur à chaque fois.

    Erreur Paperclip

    Après quelques recherches, j’ai fini par trouver que cette erreur venait du fait que mon application ne trouvait pas son chemin vers les outils d’ImageMagick dont Paperclip dépend au travers de Rmagick.

    Pour résoudre ce problème, il suffit d’ajouter un initialiseur à l’application.

    J’ai donc ajouté le fichier RAILS_ROOT/config/initializers/paperclip.rb contenant ceci :

    Paperclip.options[:command_path] = '/opt/local/bin'

    J’ai utilisé ce chemin car j’ai installé ImageMagick en utilisant MacPorts.

    Comments
  • Ignorer les changements d'espaces dans un diff SVN

    Publié le 14 novembre 2009 à 15:03 - Quick Tips

    Lorsque l’on édite un fichier, il peut arriver qu’en plus de simples modifications, certaines portions, voire le fichier entier, soient re-indentées. Malheureusement, Subversion étant bête et discipliné, un svn diff montrera les lignes modifiées mais également les lignes simplement indentées.

    Cela peut devenir gênant lorsque, par exemple, tout le fichier s’en retrouve changé.

    Pour ignorer ces différences d’espaces lors d’un diff, la commande à utiliser est la suivante :

    svn diff --extensions -bu
    Comments
  • Problème des noms de fichiers avec accents dans Subversion sous OS X

    Publié le 14 novembre 2009 à 13:48 - Quick Tips

    Si vous utilisez des fichiers dont le nom contient des accents sur un dépôt SVN, vous avez de grandes chances de rencontrer quelques soucis sous Mac, si vous avez installé Subversion avec MacPorts. Le problème vient de la différence de stockage des caractères unicode entre les plateformes Unix et OS X.

    Voici comment résoudre ce problème. C’est très simple, il suffit d’installer une variante du port subversion.

    port install subversion +unicode_path

    Si tout s’est bien passé, vous ne devriez plus avoir de problèmes.

    NOTE: j’ai ajouté cette option dans la Formula subversion de Homebrew mais c’est toujours en attente de merge de leur part…

    Comments
  • Utiliser TextMate pour les messages de commit SVN ou Git

    Publié le 27 septembre 2009 à 16:06 - Quick Tips

    Lorsque l’on utilise un éditeur de texte particulier, on apprécie de pouvoir l’utiliser comme éditeur par défaut pour peu tout. Cela comprend également les messages de commit des outils tels que SVN ou Git.

    Malheureusement, utiliser un éditeur graphique pour cela n’est pas toujours trivial.

    La commande mate propose l’option -w qui permet de signifier que l’on veut attendre que TextMate en ait fini avec le fichier pour reprendre la main.

    Il est vrai que TextMate intègre les fonctionnalités SVN et Git. Personnellement j'ai toujours préféré m'occuper de ces choses là en ligne de commande... chacun son truc...

    Pour SVN

    Il y a plusieurs façons de dire à subversion d’utiliser tel ou tel éditeur, le plus simple est de donner une valeur à la variable SVN_EDITOR :

    export SVN_EDITOR="mate -w"

    Pour Git

    Pour rester dans l’utilisation habituelle de Git, on utilisera la commande suivante :

    git config --global core.editor "mate -w"
    Comments
  • Relever automatiquement les mails des sous dossiers dans Thunderbird

    Publié le 27 septembre 2009 à 15:49 - Quick Tips

    Depuis plusieurs années maintenant, j’utilise pour lire mes mails le logiciel Thunderbird. Pratique et efficace, il n’en est pas moins doté de certains défauts plus que gênants…

    L’un d’eux est que Thunderbird ne relève pas automatiquement les mails dans les sous dossiers. Cela devient très gênant lorsque l’on utilise un filtrage des messages à la source, autrement dit, côté serveur.

    Il existe toutefois une solution. Il est possible de préciser, pour chaque dossier, que l’on souhaite que Thunderbird vérifie les nouveaux messages.

    Pour ce faire, il suffit de faire un clic droit sur un dossier puis sur Propriétés….

    Dans la fenêtre qui s’ouvre, cochez la case Surveillez les nouveaux messages dans ce dossier :

    Thunderbird properties

    Voilà, à ce jour, le mieux que l’on puisse faire, mais c’est mieux que rien.

    Comments