Rails plugin: named fixtures exporter
Pour ceux qui comme moi utilisent des fixtures nommées dans rails 2.x, vous avez sans doute été confrontés au problème de maintenance de ces pas si petits fichiers yaml.
Le problème quand on travaille sur un projet faisant des calculs sur plusieurs modèles et donc tables, c’est qu’on doit tester un maximum de cas afin d’être sûr de ne rien broyer en cas de mauvaise optimisation. Il faut donc des jeux de données assez conséquents et les fixtures peuvent jouer ce rôle. La blague, c’est qu’en simplifiant les liaisons entre les fixtures en utilisant des noms et non plus les id, on se retrouve avec un système encore plus complexe à gérer quand le volume de données grandit.
Pour répondre à ce problème, voici un petit plugin pour rails 2.x permettant d’exporter le contenu de la base de données dans des fichiers de fixtures. La différence avec ceux existant déjà tient dans un fait simple : les relations belongs_to et has_and_belongs_to_many sont gérées avec le nom des fixtures.
Un exemple sera plus parlant :
class Message < ActiveRecord::Base belongs_to :sender belongs_to :recipient
has_and_belongs_to_many :medias end
$> rake db:fixtures:display_named --- sent_message_751373555: body: qu'en penses-tu ? sender: fabien type: SentMessage sent_at: 2008-06-12 15:28:43 Z subject: de bien belles fraises draft_message_893975074: recipient: etienne sender: fabien type: DraftMessage subject: "RE : invitation jacuzzi" sent_message_751373556: body: le meilleur jus d'oranges du monde! recipient: etienne sender: fabien type: SentMessage sent_at: 2008-06-19 15:25:43 Z subject: tropicana 2 read_at: 2008-06-26 14:40:53.707300 Z medias: strawberry_sunset received_message_507475146: body: everything's ok recipient: fabien sender: etienne type: ReceivedMessage sent_at: 2008-06-19 15:29:00 Z subject: test read_at: 2008-06-26 13:54:50.333372 Z
Le plugin va regarder pour chaque modèle spécifié les relations à prendre en compte, parcourir chaque entrée dans la base de données et pour chaque relation le plugin va chercher dans les fichiers de fixtures le nom de la fixture associée à l’entrée lue. Si aucun nom de fixture n’existe, il est crée en se basant sur la colonne title, name ou le nom de la classe suivie de l’id. L’écriture du fichier se faisant après le traitement, il est possible de rafraîchir les fixtures d’un modèle sans perdre les noms déjà présents.
2 rake tasks sont disponible : export_named et display_named. En installant le gem progressbar, vous aurez une barre de progression vous indiquant l’avancement si vos fixtures sont conséquentes.
Il y a encore des lacunes (doublons non gérés) et il manque quelques tests, mais la base du plugin est présente et fonctionnelle.
Pour l’installation du plugin :
$> ./script/plugin install http://named-fixtures-exporter.googlecode.com/svn/trunk/named_fixtures_exporter
Posted in rails | no comments |
dynamisme du langage et patch
Développant un projet faisant un appel à un webservice pour un client, je dois passer des Arrays tel un formulaire html classique. J’ai donc naturellement utilisé les fonction réseau du langage Ruby, vu que le framework que j’utilise pour ce projet n’est autre que le Ruby on Rails. Je me retrouve donc avec une librairie maison pour gérer mes appels vers ce webservice, mais petite surprise dans l’encodage des fameux Arrays : les entrées du tableaux sont simplement concaténées les unes aux autres.
On est loin de ce que devrait faire un Array dans ce cas précis !
Pour rappel, un Array nommé test avec 3 valeurs passé dans une requête POST devrait ressembler à ceci :
test[]=one&test[]=two&test[]=three
En fouillant quelque peu sur le net, on trouve en effet mention de ce bug dans la fonction censée encoder les paramètres dans un format de formulaire web. Bug ouvert il y a environ un an et toujours pas fermé bien que le patch ait été posté. On trouve même un exemple du comportement normal avec … PHP.
Ne souhaitant pas modifier les sources du langage installé sur mon système pour éviter de devoir reproduire la même chose sur les serveurs en production, j’ai décidé de tirer partie du côté dynamique du Ruby en redéfinissant la fonction dans ma petite librairie.
module Net::HTTPHeader
def set_form_data(params, sep = '&')
params_array = params.map do |k,v|Â
v.inject([]){|c, val| c << "#{urlencode(k.to_s)}=#{urlencode(val.to_s)}"}.join(sep)
end
self.body = params_array.join(sep)
self.content_type = 'application/x-www-form-urlencoded'
end
end
Ca fait vraiment plaisir de travailler avec un langage certes imparfait mais qui permet des corrections dynamiques sans hack immonde ou patch totalement horrible à maintenir en production.
Posted in geek | no comments |