Développement Web Ruby
par Sylvain CLAUDEL

Derniers posts

Backports : le gem qui fait ce qu'il dit : utiliser les fonctions de ruby 1.9 avec ruby 1.8

Date d'édition 2011-08-26 à 19:32

Votre application n'est pas encore prête à passer à ruby 1.9, mais ça vous arrangerez bien d'avoir des nouvelles fonctions de ruby 1.9 pas de problème il existe le gem backports

Voici le lien des sources et de la doc : https://github.com/marcandre/backports

Valium le gem qui allège votre CPU et votre mémoire lors d'une récupération limitée des champs d'un objet

Date d'édition 2011-08-25 à 15:53

Il arrive souvent que l'on ai besoin que de certains champs lors de la récupération d'objets sérialisés en base de données.

Par exemple imaginons que nous ayons 10000 utilisateurs (avec email, adresse, nom, prenom, ...) et que nous souhaitons afficher la liste de ce qui ce sont inscrit depuis 2 mois, seul l'email nom et prénom nous intéresse.

On pourrait faire ceci :

User.where("created_at > ?", 2.months.ago).each{ |u|

  # u est de la classe User

  print [u.name, u.firstname, u.email].join(" ")

}

Avec valium on peut faire ça (et on a intérêt) :

User.where("created_at > ?", 2.months.ago)[:email, :name, :firstname].each{ |u|

  # u est un array

  print [u[1], u[2], u[0]].join(" ")

}

Doc et source : https://github.com/ernie/valium#readme

La page des benchmarks est aussi intéressante (sachant qu'en plus les tests ont été fait avec ruby 1.9.3 et Rubyonrails 3.2)

RubyOnRails was changed change pour les attributs des models

Date d'édition 2011-08-23 à 16:20

Dans les models rubyonrails il existe une tripotée de méthodes pour les attributs. Vous pouvez avoir un aperçu de ces méthodes dans le module ActiveRecord::Dirty (https://ar.rubyonrails.org/classes/ActiveRecord/Dirty.html)

Voici la traduction en français de la doc RoR : 

Détecter les changements des attributs non-sauvegardés.

Un nouvel objet instantié est inchangé :


person = Person.find_by_name('uncle bob')
person.changed?       # => false

Changeons le nom :


person.name = 'Bob'
person.changed?       # => true
person.name_changed?  # => true
person.name_was       # => 'uncle bob'
person.name_change    # => ['uncle bob', 'Bob']
person.name = 'Bill'
person.name_change    # => ['uncle bob', 'Bill']

En sauvegardant les changements :


person.save
person.changed?       # => false
person.name_changed?  # => false

En assignant de nouveau l'ancienne valeur l'attribut est inchangé:


person.name = 'Bill'
person.name_changed?  # => false
person.name_change    # => nil

Quels sont les attributs qui ont changé ?


person.name = 'bob'
person.changed        # => ['name']
person.changes        # => { 'name' => ['Bill', 'bob'] }

Avant de modifier sur place :


person.name_will_change!
person.name << 'by'
person.name_change    # => ['uncle bob', 'uncle bobby']

Pratique lors des callbacks (before_save, after_save, before_create, ...) pour faire des logs en base de données ou autres.

Ruby hash et struct ils ont chacun leur cas d'utilisation

Date d'édition 2011-08-23 à 15:55

Si vous utilisez les hash pour stocker tout et n'importe quoi, vous allez perdre en performance. L'intérêt d'un hash est comme il se définit d'ailleurs un tableau indexé. Il vous permet de trouver (rechercher) un enregistrement par sa clé.

Si vous avez besoin de faire un cache local des utilisateurs d'un système par exemple le hash est bien adapté !

users = {}

# Stocke les utilisateurs dans un hash avec pour index la clé primaire de l'utilisateur : id

User.all.each{ |u| users[u.id] = u }

Par contre si vous avez besoin de stocker des infos d'un contact (nom, prénom, age, ...), c'est à dire une liste finie et connue de clé, il vaut mieux utiliser un struct :

# Ce qu'il ne faut pas faire

user = { :name => "MON NOM", :email => "bla@gmail.com" }

# Ce qu'il faut faire

U = Struct.new(:name, :email)

user = U.new("MON NOM", "bla@gmail.com")

Apparemment les struct seraient à peu près 100 fois plus performant que les hash. Donc pour résumer si les clés sont connues à l'avance utilisez des Structs.

Rubyonrails to_json inclure exclure et appels de méthode

Date d'édition 2011-08-22 à 09:59

La sérialisation en json est bien pratique pour faire des API, en effet le json est beaucoup moins verbeux que le xml. De plus avec Rails 3.1 les exports ne se font plus avec xml mais json par défaut. Voici un post-it :

konata = User.find(1)
konata.to_json
# => {"id": 1, "name": "Konata Izumi", "age": 16,
"created_at": "2006/08/01", "awesome": true}

Les options :only et :except peuvent être utilisé pour limiter les attributs des models lors de la sérialization json. Par exemple :


  konata.to_json(:only => [ :id, :name ])
# => {"id": 1, "name": "Konata Izumi"}
konata.to_json(:except => [ :id, :created_at, :age ])
# => {"name": "Konata Izumi", "awesome": true}

Pour include des méthodes sur des models, utilisez :methods.


  konata.to_json(:methods => :permalink)
# => {"id": 1, "name": "Konata Izumi", "age": 16,
"created_at": "2006/08/01", "awesome": true,
"permalink": "1-konata-izumi"}

Pour inclure une association, utilisez :include.


  konata.to_json(:include => :posts)
# => {"id": 1, "name": "Konata Izumi", "age": 16,
"created_at": "2006/08/01", "awesome": true,
"posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
{"id": 2, author_id: 1, "title": "So I was thinking"}]}

Plusieurs niveaux d'association peuvent être géré par to_json :


  konata.to_json(:include => { :posts => {
:include => { :comments => {
:only => :body } },
:only => :title } })
# => {"id": 1, "name": "Konata Izumi", "age": 16,
"created_at": "2006/08/01", "awesome": true,
"posts": [{"comments": [{"body": "1st post!"}, {"body": "Second!"}],
"title": "Welcome to the weblog"},
{"comments": [{"body": "Don't think too hard"}],
"title": "So I was thinking"}]}
Intégralement pompé mais traduit à partir de https://apidock.com/rails/ActiveRecord/Serialization/to_json
Développement ruby et geekeries - rivsc