Dans le meilleur des mondes, le développement d'une application Ruby on Rails coïncide avec la création d'un nouveau schéma. La base de données évolue en même temps que l'application et elle respectera donc les conventions d'ActiveRecord.
Il s'agit du cas idéal car vous n'avez aucune configuration à effectuer pour vos modèles et vous pouvez pleinement profiter des migrations. La vitesse de développement est donc à son maximum.
Mais dans le milieu professionnel, les bases de données « legacy » sont omniprésentes.
Un schéma Oracle imposant qui ne respecte aucune de nos conventions et que vous ne pouvez pas modifier car d'autres applications se basent déjà sur lui.
La seule chose que vous pouvez faire c'est créer des vues dans votre schéma et cela s'avère souvent très utile. Mais ça ne suffit pas.
Cela signifie-t-il que Rails ne conviendra pas pour ce projet et que vous allez devoir repasser au développement Java? Heureusement pour nous, la réponse est non! :-)
Comme vous le savez tous, pour qu'un schéma de données soit "compatible" avec ActiveRecord, il doit respecter certaines conventions. Ainsi, le nom d'une table doit être le nom du modèle au pluriel (User -> Users) et votre clé primaire doit être une valeur numérique auto-incrémentée nommée ID.
Le verbe DOIT n'est cependant pas correct. Si ces conventions sont respectées vous n'aurez pas à configurer vos modèles, le mapping entre votre objet Ruby et votre table en base de données sera effectué automatiquement. Mais si les conventions ne sont pas respectées, vous avez toujours la possibilité de configurer vos modèles vous-même!
Prenons le schéma suivant :
Il ne respecte aucune des conventions d'ActiveRecord. Prenons la table 'my_users'. Son nom devrait être 'users' et sa clé primaire 'id'. Ici son nom est 'my_users' et sa clé primaire est 'my_pk'.
Je travaille avec une base Oracle, les champs auto-incrémentés comme en MySQL n'existent pas. Une séquence doit être utilisée à la place. Séquence que j'ai appelée 'my_users_autoi'.
Voici à quoi ressemble ma classe User:
class User < ActiveRecord::Base
set_table_name 'my_users'
set_primary_key 'my_pk'
set_sequence_name 'my_users_autoi'
end
Comme vous pouvez le voir, ce n'est pas sorcier. Vous pouvez maintenant manipuler votre modèle, toutes les opérations CRUD sont à votre disposition. Et lorsque vous insérez un nouvel utilisateur, vous pouvez constater que votre séquence est utilisée pour lui assigner sa clé primaire.
Un utilisateur peut écrire des articles. Il y a donc une relation de un à plusieurs entre ces deux entités. La classe article est assez classique, son nom est standard et elle possède un champs ID.
Le nom de la clé étrangère n'est cependant pas correct. Les conventions d'ActiveRecord demandent une clé étrangère nommée user_id.
Il faut donc la configurer dans notre modèle et également ajouter la relation dans la classe User:
class Article < ActiveRecord::Base
belongs_to :user, :foreign_key => 'by_user'
end
class User < ActiveRecord::Base
...
has_many :articles, :foreign_key => 'by_user'
end
Vous pouvez alors commencer à minipuler vos données :
((
usr = User.create(:pseudo => 'antho', :email => 'ahe@me.com')
Article.create(:title => 'My first article', :user => usr, :creation_date => Date.today)
usr.articles.first.title # => 'My first article'
))
Voilà déjà une bonne chose de faite. La table Ranking est cependant plus ennuyeuse.
Les utilisateurs peuvent voter pour des articles en attribuant un côte de 1 à 5.
La clé primaire de la table Ranking est composite : elle est basée sur BY_USER et FOR_ARTICLE.
Le problème est qu'ActiveRecord ne gère pas les clés primaires composites. Heureusement, il existe une
librairie
permettant de combler ce manque. Installez-la en suivant la démarche énoncée sur le site de l'auteur.
Une fois la manipulation effectuée, créez votre classe Ranking et modifiez vos précédentes classes pour refléter cette nouvelle association :
class Ranking < ActiveRecord::Base
set_table_name 'ranking'
set_primary_keys :by_user, :for_article
belongs_to :user
belongs_to :article
end
class User < ActiveRecord::Base
set_table_name 'my_users'
set_primary_key 'my_pk'
set_sequence_name 'my_users_autoi'
has_many :articles, :foreign_key => 'by_user'
has_many :rankings, :foreign_key => 'by_user'
end
class Article < ActiveRecord::Base
set_sequence_name 'articles_autoi'
belongs_to :user, :foreign_key => 'by_user'
has_many :rankings, :foreign_key => 'for_article'
end
Vous pouvez maintenant permettre aux utilisateurs d'attribuer une note à un article :
rk = Ranking.new
rk.rank = 5
rk.by_user = usr.my_pk
rk.for_article = usr.articles.first.id
rk.save
Remarquez que vous devez spécifier explicitement la clé primaire (usr.my_pk) plutôt que de passer directement le modèle (usr).
Et bien voilà, je pense que vous pouvez maintenant affirmer que développer une application Rails basée sur un schéma existant est tout à fait réalisable. Et comme toujours, cela reste très simple!