Affichage des articles dont le libellé est Ruby on Rails. Afficher tous les articles
Affichage des articles dont le libellé est Ruby on Rails. Afficher tous les articles

samedi 21 janvier 2012

Nouvelle version 3.2 de #rails

La version 3.2 de ruby on Rails est arrivée.

Les principales  nouveautés sont les suivantes:

  • Nouveau système de cache du code ruby de l'application. Le framework détecte si un fichier source à changé et dans l'affirmative recharge le code.  
  • Une extension pour examiner les requêtes SQL (mode explain)  
  • Un nouveau système de log.
  • La documentation dans le format EPUB, kindle etc

Et encore plein de bonnes choses




L'installation est toujours aussi simple :
rvm gem install rails

(5 minutes après)

rails new myAppl

puis
cd myApp
rails server

Et par magie dans le navigateur : localhost:3000



samedi 8 octobre 2011

Une tasse de coffeescript

Coffeescript est un nouveau langage de programmation qui génère du javascript. Le site officiel est ici.

 Ce langage est remarquable, il fait parti des DSL (domain specific language). Son auteur Jeremy Ashkenas a démarré en utilisant un livre très connu des hackers : Comment ecrire son propre langage de programmation.
La première version de coffeescript était en Ruby, un langage très adapté pour les DSL. Les versions suivantes  de coffescript sont en  coffeesript...
Coffeescript utilise la bombe du moment 'node.js' comme interpréteur.


Le programme javascript généré peut s’exécuter dans un navigateur ou sur une instance de node. La syntaxe de coffeescript est un mélange de Ruby et de Python dont il reprend les principes d'indentation.
Un script coffeescript par convention prendra l’extension '.coffee'
La génération du javascript se fait par la commande coffee -c monscript.coffee. On obtiendra ainsi  un  programme monscript.js. Ce programme répond à tous les critères de qualité des outils comme jslint.
Sans l'option '-c' le script est  traduit et exécuté directement  par node.js

Le framework Ruby on Rails dans sa dernière version intègre ce générateur de code.
Il suffit de placer un script avec l'extension coffee dans le répertoire javascript pour qu'il soit compilé et rendu disponible à l'application.

Ici j'utilise jquery via coffeescript :

$ ->
   alert "mon premier script avec coffeescript" 


Après un temps d'adaptation de quelques jours, j'ai du mal maintenant à écrire directement du javascript. D'autant qu'il se charge du sale boulot: déclaration des variables locales, closures etc.
La simple ligne : puts = console.log permet d'utiliser la notation classique puts "mon message" comme en Ruby.
J'ai profité du site www.scoop.it pour rassembler des liens sur le sujet : lien de curation ici.





vendredi 7 octobre 2011

Soirée rails france paris.rb

Mardi soir direction le café 'rubis'  rue du Maine pour une soirée organisée par rubis ou rails france. Nous sommes une bonne quarantaine à nous retrouver dans une salle trop petite. Le rétroprojecteur a fait faux bond, aussi  au lieu d'ajourner la soirée, une présentation est improvisée sur un mac book Air. Il s'agit du projet sproutcore.

C'est un framework javascript qui peut s'interfacer facilement avec Rails.
Ce projet se veut plus complet et intégré que backbone.js. Ce type de produit sert à développer des applications pour clients riches, pas pour faire des sites web classiques.

La présentation est là : (suivre le lien).

La soirée m'a permis d'admirer la maquette du nouveau site rails France avec une page 404 prometteuse
 
Tout de même une bonne soirée

mardi 27 septembre 2011

Rails 3.1 plus qu'une nouvelle version

La sortie de la version 3.1 de Ruby on Rails est un évènement qui marquera le web 2.0. C'est le premier framework qui se met au service des  composants qualifiés à tort de secondaires: Le javascript et le CSS.
La force de  Rails 3.1 est d'arriver à fédérer les meilleurs produits tout en restant dans son rôle de cadriciel.

Les éléments forts sont:
a) Utilisation de node.js pour proposer le facilitateur de javascript  coffeescript. On peut imaginer les montages a faire entre rails et node.js
b) Jquery est mis en avant. C'est tout le  javascript et le css (avec le générateur Sass ) qui vont bénéficier d'un nouveau traitement par le biais des assets. Il suffit d'ajouter son script dans un répertoire dédié pour qu'il soit ajouté et compressé avec jquery.
c) Le middleware : le lien entre la requête http et le langage est réalisé par le système Rack. Ruby est à ce jour le seul langage à proposer une boite à outil de ce type.


arborescence d'un projet Rails
Sur cette copie d'écran, on notera l'apparition du répertoire assets qui contient trois dossiers: un pour le javascript , un pour le css et un pour les images. Les trois fonctionnent de manière identique et dans le même but: concaténer les fichiers en un seul pour réduire le nombre de connexion réseau nécessaires à l'obtention d'une page complète.

Utilisation du javascript.

Tout commence par la création d'une application Rails par la commande éponyme: 
rails mon_projet  . 
La commande rails s'est étoffée :
La  première page est activée en générant un controleur (ex: rails g controller commun index ) . 
Tout fonctionne : 


Et là, la magie commence, deux lignes de javascript déposé dans le répertoire assets et aussitôt Rails vous sert jquery.


Si on ne veut qu'une seule requete pour récupérer le javascript dans l'environnement de développement,  une petite modification des fichiers de configuration s'impose.

Ces lignes dans  le fichier environments/development.rb
précisent de :

 config.assets.compress = true                                    # compresser tout le contenu d'assets
  config.action_controller.perform_caching = tr         # Utiliser un cache serveur
  config.assets.js_compressor  = :uglifier                    # Utiliser uglifier comme minificateur de javascript  
  # Expands the lines which load the assets
  config.assets.debug = false                                      # enlever le mode debug

A la premiere requete :
Rails va compiler les programmes coffeescript s'ils existent. Il va ensuite assembler les fichiers javascript, les concaténer et les mettre en cache (nettoyage du cache : rake tmp:clear).

Avec comme résultat : 1 css et 1 javascript minifié
   

La version 3.0 était déjà une révolution: c'était la fusion de deux projets opensources majeurs (Rails et merb) , alors que le fork est le mode de vie normal d'un projet. La version 3.1 fait encore plus fort et réalise la synthèse de deux idées puissantes : les frameworks légers et agiles  pour le web et la reconnaissance du javascript (coté client et serveur).

samedi 29 janvier 2011

Cucumber, RSPEC :Comment une rondelle de concombre peut changer votre vie



Si Ruby on rails connait un succès croissant, c'est grace notamment à sa capacité à s'intégrer dans des démarches agiles de gestion de projet. Je connaissais pour la pratiquer (à ma façon) la méthode TDD : conduite du développement par les tests. Dans cette technique le développement du produit commence par la réalisation de tests (unitaires,d'intégration et fonctionnels) avant toutes choses. Le cadriciel Rails intègre nativement tout ce que vous avez besoin pour couvrir ces trois volets de test. Rails propose en plus l'utilisation des fixtures (garnitures) pour remplir ou manipuler les données de tests. le TDD propose des objets 'fictifs' mock ou stub afin de retarder le développement en 'dur' des objets.

J'ai souvent entendu parlé de RSPEC , un environnement de test offrant des techniques de développement basées sur le comportement de l'utilisateur (des histoires) : Behaviour DD (BDD).
La lecture de ce livre m'a ouvert des nouveaux horizons



Un fichier RSPEC (Ruby spécification) va décrire des évènements , des actions ou des états et comment le système doit réagir vis à vis de ces situations. RSPEC utilise un DSL (langage spécifique à un domaine) orienté développeur. Les RSPEC seront traduits en assertions de test.

 2 describe Game do
3 describe "#start" do
4 it "sends a welcome message" do
5 output = double('output')
6 game = Game.new(output)
7
8 output.should_receive(:puts).with('Welcome to Codebreaker!')
9
10 game.start
11 end
12
13 it "prompts for the first guess"
14 end


Ce livre consacre plusieurs chapitres à un projet appelé : cucumber (concombre). Cucumber est le projet qui réalise le rêve de tous les développeurs: il traduit les spécifications de votre client(sponsor-moa etc) en test de comportement (RSPEC :la synthèse des 3 types de test) .

Ici le DSL est orienté client (MOA). Le client va décrire avec ses mots des situations. Exemple:


Feature: code-breaker starts game

As a code-breaker
I want to start a game
So that I can break the code

Scenario: start game
Given I am not yet playing
When I start a new game
Then I should see "Welcome to Codebreaker!"
And I should see "Enter guess:"
Cucumber va traduire les termes :'given', 'when' 'then' en scénario de test de type RSPEC.
Ce DSL existe en version française.

(ressource: http://blog.octo.com/cucumber-pour-les-railers/)



Pour terminer, il convient de signaler que cucumber fonctionne avec watir et selenium qui sont deux outils complémentaires de test fonctionnel


(synthèse des composants: cliquer pour agrandir)



Il est plaisant de voir ces outils envahir le monde Java. C'est par ce moyen que Ruby
penetre dans les entreprises.

mercredi 26 janvier 2011

Administration d'une application Rails avec typus


Typus est un gem pour le cadriciel Ruby on Rails qui permet simplement de définir des rôles et des permissions sur une application notamment pour les applications CRUD. Typus se définit comme : "Admin Panel for Ruby on Rails applications". Le lien vers github est ici.
La démo en ligne est ici.
Les permissions sont gérées par des ACL stockées dans des fichiers YAML.

lundi 17 janvier 2011

Deux projets majeurs dans linux magazine



Dans le numéro (134) de janvier 2011 de Linux Mag, deux articles méritent une attention particulière.

SONAR

Le projet SONAR (lien ici) qui permet de mesurer la qualité du code. En partant d'une charte de bonnes pratiques, le système verifie le respect de ces normes dans le code. Il est utilisé principalement pour des projets JAVA ou PHP.
Le détail qui tue dans l'article: pour la partie restitution (web) , SONAR utilise Ruby on Rails...

Pour ma part ma vision du bon code est la suivante:




Puppet


Le projet Puppet (lien ici) gère de manière centralisée des configurations de machine. Il utilise des templates 'erb' comme patron. Bref Puppet est un projet en Ruby.
(erb: Embedded RuBy ).

2011

2011 sera l'année du Cloud et donc de ruby qui couplé à Rails s'impose comme la solution simple de déploiement dans un nuage.

vendredi 31 décembre 2010

activeRecord sans Rails et métaprogrammation

Dans un post précédant, je détaillais le chargement d'une base NoSQL à partir d'une base de données relationnelle en mentionnant l'usage d'Active record sans Rails.
ActiveRecord et maintenant ActiveRelation sont des ORM qui s'utilisent indépendamment des autres composants de Rails.
Il suffit pour cela d'instancier un objet Base en lui fournissant les éléments de connexion à la base de données.


(clic pour agrandir)




J'utilise par la suite ActiveRecord en métaprogrammation :

def _create_class(tclass)

uftclass = "Tempo_" + tclass

eval "

class #{uftclass} < ActiveRecord::Base

set_table_name \"#{tclass}\"

end

"

fields= eval "#{uftclass}.column_names"



end



Ainsi je crée des classes à la volée qui héritent d'Activerecord. Cette opération dynamique se fait par une clause 'eval'.

L'instanciation se fait plus loin dans le code par là aussi un éval:


(clic pour agrandir)

dimanche 5 décembre 2010

django, rail3 comment démarrer



On va s'amuser avec les deux frameworks champions: django / python d'un coté et Rails3 / Ruby de l'autre.

Installation de django.

Avec django, il est est plus prudent d'utiliser la dernière version du logiciel. django se présente sous la forme d'une archive standard. Il s'installe en tapant dans le répertoire de l'archive:
python ./setup.py install

Installation de Rails3


L'utilisation de rvm est hautement recommandée.
La commande classique d'installation d'un gem:
rvm gem install rails
(j'ai utilisé la version 1.9.2 de Ruby sous rvm)
L'avantage de Rails est qu'il utilise le gem 'bundler' . Au démarrage d'une application, le fichier Gemfile listant les dépendances est lu et les gems manquants sont installés.



Création d'une application avec django

Django manipule la notion de projet et d'application. Un projet regroupe plusieurs applications.

La création du projet se fait par la commande :

/usr/local/bin/django-admin.py startproject djgolfare


Cette commande crée un répertoire au nom du projet. Ce répertoire contient un programme manage.py qui permet d'ajouter des applications par:

python ./manage.py startapp tableboard

L'arborescence sera de la forme :




Création d'une application avec Rails3

La commande à passer est :
rails new r3golfare

Une série de fichier et de répertoire est générée:



Configuration de la base de donnée pour django

Toute la configuration est contenue dans le fichier settings.py. C'est donc de la syntaxe python.


12 DATABASES = {
13 'default': {
14 'ENGINE': 'sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
15 'NAME': '/usr/local/djgolfare/essai', # Or path to database file if using sqlite3.
16 'USER': '', # Not used with sqlite3.
17 'PASSWORD': '', # Not used with sqlite3.
18 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
19 'PORT': '', # Set to empty string for default. Not used with sqlite3.
20 }
21 }
22

Configuration de la base de donnée pour Rails


Un fichier database.yml se trouve dans le répertoire 'config'
Rails utilise le format YAML pour ces fichiers de configuration


 1 # SQLite version 3.x
2 # gem install sqlite3-ruby (not necessary on OS X Leopard)
3 development:
4 adapter: sqlite3
5 database: db/development.sqlite3
6 pool: 5
7 timeout: 5000
8
9 # Warning: The database defined as "test" will be erased and
10 # re-generated from your development database when you run "rake".
11 # Do not set this db to the same as development or production.
12 test:
13 adapter: sqlite3
14 database: db/test.sqlite3
15 pool: 5
16 timeout: 5000
17
18 production:
19 adapter: sqlite3
20 database: db/production.sqlite3
21 pool: 5
22 timeout: 5000


La base est déclinée en trois instance, une pour chaque environnement.


Le détail du répertoire config est ici :



Lancement de l'application django

 1 >python ./manage.py syncdb
2 No fixtures found.
3 >python ./manage.py runserver
4 Validating models...
5 0 errors found
6
7 Django version 1.2.3, using settings 'djgolfare.settings'
8 Development server is running at http://127.0.0.1:8000/
9 Quit the server with CONTROL-C.
10


Lancement d'un application Rails3


32 root@eric-1001PX:/usr/local/r3golfare# rails s
33 => Booting WEBrick
34 => Rails 3.0.3 application starting in development on http://0.0.0.0:3000
35 => Call with -d to detach
36 => Ctrl-C to shutdown server
37 [2010-12-04 17:21:17] INFO WEBrick 1.3.1
38 [2010-12-04 17:21:17] INFO ruby 1.8.7 (2010-08-16) [i686-linux]
39 [2010-12-04 17:21:22] INFO WEBrick::HTTPServer#start: pid=2639 port=3000
40

Dans un autre post, je détaillerai la mise en place d'un patron CRUD dans ces deux frameworks.

dimanche 21 novembre 2010

La transition entre les SGBDR et les bases NoSQL



Le contenu des bases NoSQL (Not Only SQL ) n'est pas issu d'une génération spontanée. Une grande partie des informations provient des base de données 'traditionnelles'. Comment passer d'un modèle à un autre ?. Des interfaces vont devoir être développées, voici ma contribution : le module nosql.rb disponible sur Lemon-labs (github).

Ce module rassemble des informations d'une base de données (Postgresql , oracle , mysql etc ) et injecte les données dans une base NoSQL (ici couchdb).

Configuration

Le programme utilise un fichier de syntaxe YaML qui va décrire les sources, les filtres à utiliser et la cible.

Datasource:
adapter: sqlite3
database: db/development.sqlite3
poll: 5
timeout : 5000
Tables:
table_fact: projets
primarykey: id
table_dimension:
filieres:
primarykey: id
foreignkey: filiere_id
technos:
primarykey: id
foreignkey: techno_id
filters:
attributes: id
regexp: create,_id,update
append:
attribute: type,ROW
options:
NoNil: 1
target:
# output: 1
couchdb: http://localhost:5984/projets
Avec les paragraphes suivants:
  • Datasource : c'est l'accès à la base de données relationnelle. Sa syntaxe est celle ActiveRecord de Rails.
  • Table : la première partie décrit la table principale (ou table de fait) . La suivante liste toutes les tables de détails (dimension) et les champs utilisés pour les liens.
  • Filter: le programme constitue un tableau associatif pour la ligne à créer. Les filtres servent à supprimer des champs (exemple : les champs des clés primaires ou étrangères)
  • Append: Cet option ajoute des attributs fixes (exemple : type de ligne)
  • Options : fixe les règles de gestion des champs vides.
  • Target : précise la base NoSQL à charger.

Le programme va récupérer les informations sur les tables, les champs et les liens entre les tables.
Ligne par ligne, le module va entièrement dénormaliser la base pour ensuite l'injecter dans une base NoSQL.


API REST
Le module nosql.rb est associé avec un module nosqlonweb.rb qui lui ajoute un format d'API REST.



Le menu delete_row permet de supprimer toutes les entrées d'une base NoSQL sauf les documents de restitutions.

Le lancement du module web se fait par la commande :
ruby nosqlonweb.rb . Le framework utilisé est 'sinatra'.
L'API retourne ses résultats au format JSON.

Bases supportées
L'utilisation d'active record rend le programme compatible avec la majorité des bases de données. PostgreSQL, Oracle , SQLite, Mysql etc.

samedi 18 septembre 2010

#rails vs #java : video



Cette video reprise par le blog http://www.geeek.org/post/2007/05/20/Ruby-on-Rails-vs-Java

Illustre la complexité d'une architecture java JEE.

Dans les commentaires du post quelques perle dont une très plaisante :

comparer par exemple php (et rails) à java c'est comme comparer une twingo à une mercedes classe S.

Ruby ne rend pas forcement vos développements meilleurs , il rend VOS DEVELLOPEURS meilleurs (AMHO je crois qu'ils les rend plus intelligents)

mercredi 28 juillet 2010

5 astuces pour #rails


1) La mise au point.
Le debug du code en Rails est très facile.
Il faut tout d'abord avoir installé le gemme ruby-debug.
Puis on peut ajouter "debugger" aux endroits stratégiques . "debugger" qui va provoquer un point d'arrêt dans le code.
Le lancement du serveur se fera avec l'option script/server --debugger

Avec cette option le serveur va exécuter le code jusqu'au point d'arrêt et vous rend la main. Vous pouvez alors examiner les variables, faire du ligne à ligne.

Sans utiliser le debug , il est parfois utile d'accéder aux paramètres d'une transaction, il suffit d'insérer dans le code du contrôleur l'instruction "raise" pour provoquer un plantage et un affichage de toutes les variables de la requete.

Enfin , dans les vues la fonction "debug(nom_de_variable") affiche le contenu des objets, des lignes d'un tableau etc.

2) Les observateurs.

Le design pattern 'observer' permet d'introduire une dépendance souple entre deux classes.
Ce motif sert de lien entre deux classes en observant les évènements des instances d'une classe.
Le cas d'utilisation simple est le déclenchement de la journalisation à la suite d'un évènement sur un objet. Par l'utilisation des observers, on évite de polluer le code d'une classe avec des opérations qui ne sont pas directement dans le périmètre d'un objet.

Je m'en sert pour tenir à jour des compteurs de lignes.
Exemple: j'ai deux classes , une pour 'projet' et une autre pour 'tache_annuelle'. Je souhaite avoir une variable d'instance qui pour chaque projet retrace le nombre de ligne de la table des taches. Cette opération peut etre réalisée en SQL mais l'affichage de 60 projets avec pour chacun une requête SELECT COUNT plomberait les performances.

J'ai utilisé un observer qui scrute deux évènements : la création et la suppression des lignes de la table tache.

(Zeya:/usr/local/projetsawd# emacs app/models/auditeur_observer.rb)



class AuditeurObserver < ActiveRecord::Observer
observe Lignepaatec

def after_create(ligne)
@projet= Projet.find(ligne.projet_id)
@projet.paa+=1
@projet.save
end
def after_destroy(ligne)
@projet= Projet.find(ligne.projet_id)
@projet.paa-=1
@projet.save
end


end

Le fichier auditeur_observer.rb doit se trouver dans le répertoire des modèles et chargé au démarrage du serveur par l'ajout de cette ligne dans le fichier config/environment.rb

config.active_record.observers = :auditeur_observer

J'ai appris depuis qu'il est possible de générer automatique les fichiers pour les observers par la commande: script/generate observer


Zeya:/usr/local/projetsawd# script/generate observer essai_eric
exists app/models/
exists test/unit/
create app/models/essai_eric_observer.rb
create test/unit/essai_eric_observer_test.rb



3) La meta-programmation au service du DRY.

Le Don't Reapeat Yourself doit commencer à s'appliquer à soi. Ainsi , je suis parfois amené à saisir plusieurs fois la même chose ou avec quelques nuances.
J'ajoute aux formulaires de modification (action => edit) un bouton nommé 'clone' . Quand je veux obtenir une entrée qui diffère légèrement d'une autre, j'édite l'entrée servant de modèle et après quelques ajustements, je soumet le formulaire avec le bouton 'clone'. J'obtiens ainsi une nouvelle entrée avec peu de saisie.
La procédure update est chargée de propager les modifications ou de cloner, elle récupère les paramètres du formulaire et instancie un nouvel objet avec.

def update
@paatec = Paatec.find(params[:id])

if params[:commit] == 'Clone' then
@paatec_clone= Paatec.new
cle= params[:paatec].keys
cle.each do |k|

@paatec_clone.send "#{k}=" , params[:paatec][k.to_sym]
end
@paatec_clone.save
respond_to do |format|

format.html { redirect_to(@paatec_clone) }
format.xml { render :xml => @paatec_clone, :status => :created, :location => @paatec_clone }
end
else
....


La ligne magique est celle ci :
@paatec_clone.send "#{k}=" , params[:paatec][k.to_sym]

Elle illustre la puissance de la meta-programmation :
Elle appelle successivement tous les 'setter' par la méthode send. La méthode send attend en paramètre un nom de méthode: exemple objet1.send("libelle") est équivalant à objet1.libelle qui est un 'getter'. Activer un 'setter' de cette manière est plus difficile car il faut ajouter le '=' à la fin du nom de la méthode.

ps : ici la notion de 'clone' n'a pas de rapport avec la la méthode clone ou dup de ruby.





4) L'export CSV.
J'ai aussi des exports CSV à faire. Il y a plusieurs techniques , j'ai choisi celle-ci:
A ajouter dans  un contrôleur
...
require 'csv'
....

def export_csv

cond= params[:cond]
tab =cond.split ('%')


@projets= Projet.find_select(tab[0],tab[2],tab[1])
# @projets =Projet.find(:all)
report = StringIO.new
CSV::Writer.generate(report, ';') do |csv|
csv << ['Projet','Libelle','domaine','diDEV','diPROD','MOA','Filiere','Techno']
@projets.each do |projet|
csv << [projet.nom,projet.libelle,@template.sauf_null(projet,'domaine','libelle'),@template.sauf_null(projet,'didev','libelle'),@template.sauf_null(projet,'diprod','libelle'),
@template.sauf_null(projet,'moa','libelle'),@template.sauf_null(projet,'filiere','libelle'),@template.sauf_null(projet,'techno','libelle')
]
end
end
report.rewind
send_data(report.read,
:type => 'text/csv; charset=iso-8859-1; header=present',
:filename => 'report.csv',
:encoding => 'utf8'
)
end


end



Dans le code on peut constater l'utilisation de la variable @template. Cette astuce permet de réutiliser les méthodes écrites pour les vues (helpers). La variable globale @template, contient tous les helpers.

5) Le bridage de l'application.

Protéger son application par un user/password est parfois un peu lourd pour une application basique. Je désire seulement pouvoir contrôler les périodes de mise à jour. Pour cela j'utilise un filtre callback 'before_save' et before_destroy dans le modèle :

############ bloquer tout ################
before_destroy :periode
before_save :periode
#########################
def periode
errors.add_to_base("la mise a jour est interdite")
return false
end


Pour afficher l'origine de l'erreur dans les messages flash , quelques lignes dans la méthode destroy du contrôleur suffisent :


if !@lignepaatec.destroy then
flash[:notice] ="Mise a jour interdite"
end



En bonus une 6 eme astuce :

La commande: rake routes affiche toutes les url reconnues pas l'application.


portable:/usr/local/projetsawd# rake routes
(in /usr/local/projetsawd)
statuts GET /statuts(.:format) {:controller=>"statuts", :action=>"index"}
POST /statuts(.:format) {:controller=>"statuts", :action=>"create"}
new_statut GET /statuts/new(.:format) {:controller=>"statuts", :action=>"new"}
edit_statut GET /statuts/:id/edit(.:format) {:controller=>"statuts", :action=>"edit"}
statut GET /statuts/:id(.:format) {:controller=>"statuts", :action=>"show"}
PUT /statuts/:id(.:format) {:controller=>"statuts", :action=>"update"}
DELETE /statuts/:id(.:format) {:controller=>"statuts", :action=>"destroy"}




Good hacking.

mercredi 6 janvier 2010

gigya : l'api des apis.

Le site Gigya propose une API qui permet de s'authentifier sur les sites sociaux suivants:

MySpace Facebook Yahoo Friendster
Orkut Bebo WordPress Blogger
Hi5 Tagged LiveSpaces Piczo
Freewebs Livejournal BlackPlanet MyYearbook
TypePad Xanga Multiply iGoogle
Netvibes Pageflakes MiGente Vox
Ameba Livedoor Eons overblog


Par l'ajout du composant visuel sur votre site, vos utilisateurs pourront s'authentifier aupres de leurs site habituel. C'est en fait une API qui vient en surcouche de 12 autres API (Facebook,yahoo etc)



Outre le service d'authentification Gigya propose des interactions avec certains sites comme facebook.

Un article dans Rails magazine n° 5 détaille son utilisation dans Ruby on Rails.

mardi 8 décembre 2009

Less is better de david Heinemeier Hansson

Sur le site UX magazine David Heinemeier Hansson, créateur de Ruby on Rails répond à quelques questions, l'article est titré : Less is better.

Dans cet article , il expose sa vision d'un modèle économique simple :
Les entreprises de petite taille peuvent grâce au web, rayonner autant qu'une grosse entreprise. Mais elles ne doivent pas tomber dans le piège de la dispersion: Il faut rester sur son coeur de métier. Et il est étonnant de voir des start-up ne sachant pas exactement quel est leur coeur de métier. Si ton voisin vend la même chose que toi moins cher et arrive à payer ses factures, alors tu es très mal.

Il faut se consacrer sur ses produits et non pas chercher à faire 'à tout prix' plaisir aux utilisateurs pour qu'ils achètent ces produits.
Pour faire connaitre son produit , l'entreprise à deux alternatives: dépenser de l'argent ou partager largement ses connaissances sur le produit.




Cette illustration est tirée du blog : creating_passionate_users

Ainsi d'après lui, l'utilisateur est balancé entre avoir plein de fonctionnalités et pourvoir se servir d'un produit basique, simple d'emploi.


Les développeurs cherchent à sortir le produit qui tue: avec des tonnes de fonctionnalités, capable de s'adapter à tous les usages.
C'est une erreur, l'utilisateur au fond de lui souhaite ne pas se poser des questions ni être confronté à un écran rempli de case à cocher d'option.
C'est pour cela que Rails est le framework le moins paramétrable de sa catégorie, ce n'est plus un défaut, c'est une qualité. Il est prêt à l'emploi tel quel. Rien n'empêche l'utilisateur averti de modifier le comportement, mais sans utiliser une interface graphique d'administration.L'utilisateur doit faire confiance au développeur pour se voir proposer la meilleure composition en fonction de l'utilisation.

Concernant la conduite de projet.

David préconise des cycles de 3 semaines avec une équipe réduite. Une application utilisable doit voir le jour à la fin de ce délais. Puis, les décideurs et les commanditaires doivent se poser la question: est ce qu'on injecte des ressources pour une nouvelle fonctionnalités et repartir pour 3 semaines ou doit on tout arrêter et se contenter de ce résultat ?.

Concernant les spécifications détaillées.

Vouloir décrire dans un document le fonctionnement complet d'une application est illusoire et dangereux. Illusoire car, personne n'est capable ne visualiser et d'imaginer une application tel qu'elle sera dans 6 mois. Dangereux parce qu'il est très facile de modifier quelques lignes dans un document sans mesurer les conséquences sur le développement, si les spécifications sont figées, on assistera à un effet tunnel et l'application ne correspondra plus au besoin réactualisé.

Voir le post dans son contexte d'origine http://germanlinux.blogspot.com/

mercredi 25 novembre 2009

Les objets et les classes en Ruby

Le langage Ruby offre des possibilités de méta-programmation importantes.
Il exploite au mieux la souplesse que lui confère son caractéristique de langage interprété. Ce concept est poussé dans se que l'on appelle le 'duck typing' : le typage canard. A l'inverse de Java qui propose un typage dynamique, Ruby met en avant le typage dynamique. Ce n'est pas votre typage qui dicte votre comportement mais l'inverse. si marche comme un canard et si tu nage comme un canard , alors tu peux etre comme considéré un canard. Le duck typing va plus loin que ca, car il permet de modifier des comportements en cours d'exécution.

Commençons par la mise en place des objets en Ruby.
Si je pars des déclarations suivantes:

class Ma_class
def ma_methode
@x1= 1
end
end

Par irb -r maclasse.rb

Je teste :

objet1= Ma_class.new
=> #

objet1.ma_methode
=> 1
objet1.instance_variables
["@x1"]
p objet1
<Ma_class:0xb7c8483c @x1=1>

ainsi un objet est une référence vers une classe et un tableau associatif de variables. Tant qu'une variable n'est pas initialisée ou utilisée , l'objet n'en fait pas mention.

On peut continuer à explorer le contenu des objets et des classes par les méthodes :
class , superclass ou instance_methods(false)
Ici le 'false' indique de ne lister que les methodes propres à une classe (non héritées) . La méthode included_modules liste les modules utilisés.


Cela donne :

Ma_class.superclass
=> Object

> Ma_class.class

=> Class

> Ma_class.instance_variables

=> []

Class.superclass

=> Module

Module.class

=> Class

> Module.superclass

=> Object

Ma_class.instance_methods(false)

=> ["ma_methode"]

Object.class
=> Class



En remontant toute la chaine on obtient le schéma suivant:(clic pour élargir)




Il n'y a pas de grande difference en ruby entre une classe et un module. Tous les deux sont implémentés de la même façon. Par contre il n'est pas possible d'instancier un module. Les modules sont utilisés pour gérer des espaces de nommage et surtout pour réaliser du 'mixing' cad : Ajouter d'autres comportements (classes) à des classes. Exemple : dans une classe l'ajout de 'include enumerable' lui fournit une vingtaine de méthodes supplémentaires.

La méthode ancestors donne:

Ma_class.ancestors

#=> [Ma_class, Object, Kernel]

Que vient faire Ici Kernel ? . En fait ruby ajoute une pseudo classe équivalente au module kernel. Pour trouver une méthodes, ruby parcours le chemin 'rigth and up' (A droite et en haut) , les modules sont mappés sur des pseudos classes afin de se trouver sur le chemin de recherche des méthodes.

En ruby 1.9 le système est légèrement modifié par l'introduction d'une classe
'BasicObject' au sommet de la pile.

Il reste à résoudre le mystère suivant: Où sont stockés les méthodes singletons ?
La réponse srea donné sur un post consacré aux Eigenclasses en ruby.

Pour voir le post dans son contexte :http://germanlinux.blogspot.com/2009/11/les-objets-et-le-classes-en-ruby.html