Archives (février 2009)



ActiveRecord : Construire une application Rails basée sur un schéma existant



Ecrit par Anthony Heukmes le 20 février 2009 15:45

2 commentaires



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!

Plugin Ruby on Rails : gérez facilement les titres de vos pages!



Ecrit par Anthony Heukmes le 17 février 2009 20:35

0 commentaire



EasyTitles est un plugin Ruby on Rails vous permettant de gérer très facilement les titres de vos pages. Plutôt que de créer une variable @titre dans vos vues ou contrôleurs, EasyTitles vous offre une gestion centralisée des titres via des fichiers YAML. Ce plugin supporte également l'internationalisation (I18n) si vous utlisez une version de Rails >= 2.2.

Le gros avantage est que vous avez un seul fichier centralisant tous vos titres. Ceux-ci ne sont donc pas éparpillés un peu partout et sont plus faciles à mettre à jour.

Ainsi, si vous avez un contrôleur REST "Articles" (qui possède donc les méthodes CRUD de base), il vous suffit de créer un fichier YAML qui aura la structure suivante :


articles:
index: "Liste des articles"
show: "Détails d'un article"
new: "Création d'un article"
edit: "Edition d'un article"


Il ne suffit plus alors qu'à appeler la méthode easy_title dans la balise titre de votre page :


<title><%= easy_title %></title>


Cette méthode va déterminer le titre à afficher en fonction de la page courante.
Si vous êtes sur la page /articles/show, le titre "Détails d'un article" sera affiché.

EasyTitles vous permet également d'ajouter des titres par défaut.


default: "Ce titre sera affiché pour n'importe quel controller/action qui n'a pas de titre défini"
articles:
default: "Ce titre sera affiché pour toutes les actions du contrôleur articles qui n'ont pas de titre défini"
index: "Liste des articles"
show: "Détails d'un article"
new: "Création d'un article"
edit: "Edition d'un article"



Installation





  1. script/plugin install git://github.com/ahe/easytitles.git

  2. Créez un dossier titles dans votre répertoire config (RAILS_ROOT/config/titles).

  3. Si vous utilisez internationalisation (I18n), créez un fichier yml par locale (fr.yml, en.yml, ...) dans le répertoire titles.

  4. Dans le cas contraire, créez un fichier yml avec le nom de votre choix dans le répertoire titles.

  5. Insérez vos titres dans le(s) fichier(s) yml en respectant le format décrit ci-dessus.

  6. Placez la méthode helper dans votre balise titre : <title><%= easy_title %></title>