05
JAN

Apprendre Ruby on Rails avec la Ferme du Web - Partie 3

Publié le 05/01/09 à 09h33 par DJo

:

Dans les Episodes précédents ...

Partie 1: Introduction à Ruby on Rails, installation de l'environnement Ruby

Partie 2: Définition de notre projet Twitterails, création de l'architecture, configuration de la base de données MySQL

Tutorial Ruby on Rails: Partie 3

Les pré-requis: Vous avez déjà programmé dans un langage orienté objet, et devez avoir de bonnes bases en SQL.

Troisième partie: Dans cette troisième partie, nous verrons:

 

A noter que je n'ai jamais développer en Ruby on Rails, le but est de m'auto former au langage et en même temps de vous faire partager mes recherches. Si des points vous semblent flous ou incohérents, n'hésitez pas à me le faire savoir en commentaires.

Ruby on Rails - Apprendre avec la Ferme du Web

Le MVC dans Rails

Comme la plupart des frameworks, Rails utilise le design pattern MVC (Modèle Vue Contrôleur).

Schema MVC

(Schema par c-maneu)

Pour faire très simple, le MVC permet de séparer les différentes couches d'une application:

  • Vue: Toutes les templates, pages HTML etc d'un côté.
  • Modèle: La logique métier, les appels en BDD (Mapping ou pas).
  • Contrôleur: Le contrôle des actions et renvoi des bonnes informations.

Si vous voulez en savoir plus sur le MVC, allez faire un tour sur Wikipedia.

Ce qui nous intéresse maintenant, c'est comment fonctionne le MVC dans Rails !

Si nous regardons le répertoire app de notre architecture rails, nous avons:

Répertoire app Rails

 

 

 

 

C'est ici que sont stockés les éléments de l'architecture MVC sous Rails.

Vous retrouvez les dossiers Models, Views et Controllers.

Le répertoire helpers contient les "fichiers Helper", des portions de code, fonctions, réutilisables dans vos vues pour effectuer différentes opérations sans avoir à insérer trop de code Ruby dans vos vues (Toujours dans l'optique de séparer les couches).

L'architecture MVC est aussi présente dans le coeur de Rails.

En effet, il existe 3 classes pour les différentes couches:

  • ActiveRecord: La partie Modèle, la logique métier. Permet notamment le Mappage Objet-Relationnel
  • ActionController: La partie Contrôleur. En quelque sorte le chef d'orchestre du site, il permet d'analyser les URL, les fait traiter par le Modèle puis renvoi la vue correspondante.
  • ActionView: La partie vue. Cette classe permet de gérer l'affichage et le chargement des données dans les pages.

 

Modèles: Génération des modèles de notre application

Après la théorie, voici un peu de pratique, nous allons créer les différents modèles de notre application Twitterails:

  • statut
  • membre
  • follow

Dans une application PHP, nous aurions dû créer notre base de données, puis implémenter la classe associée, les méthodes CRUD ... C'est plutôt long et répétitif !

Avec Rails, tout peut être créé automatiquement: La table MySQL, la classe, les méthodes CRUD ...

C'est parti !

1) Supprimer les tables précédemment créées

Si vous avez suivi la partie 2 du tutorial, vous avez du créer vos tables sur phpMyAdmin.

En fait, il est préférable de ne pas créer les tables à la main car elles seront directement générées par Rails. Nous aurions pu garder les tables, mais pour éviter tout problèmes de compatibilités de types ou autre, je préfère les supprimer.

2) Création des modèles

Ouvrez votre invite de commande, rendez-vous dans le répertoire de l'application twitterails (A coup de cd) puis tapez:

ruby script/generate model statut

Vous devriez obtenir un log comme celui-ci:

      exists  app/models/       exists  test/unit/       exists  test/fixtures/       create  app/models/statut.rb       create  test/unit/statut_test.rb       create  test/fixtures/statuts.yml       create  db/migrate       create  db/migrate/001_create_statuts.rb

Faites la même chose pour les modèles membre et follow:

ruby script/generate model membre

ruby script/generate model follow

Voici les nouveaux fichiers générés:

Fichiers générés

Les classes de notre application dans le répertoire app/models/

Et les fichiers permettant la création de la table MySQL dans le répertoire db/migrate/

Vous pouvez constater qu'il y'a aussi des fichiers créés dans test/ mais nous les utiliserons pas pour le moment.

3) Renseignement des fichiers db/migrate/

L'étape suivante consiste à décrire nos tables dans les fichiers de création des tables, dans le répertoire db/migrate/

001_create_statuts.rb

Pour le moment, vous devriez avoir un fichier assez vide comme celui-ci:

class CreateStatuts < ActiveRecord::Migration
  def self.up
    create_table :statuts do |t|

      t.timestamps
    end
  end

  def self.down
    drop_table :statuts
  end
end

reprenons notre schéma MySQL réalisé dans la partie 2 pour le compléter:

Schema MySQL Twitterails

 

Nous allons créer notre table statuts.

Par défaut, Rails va créer un champs id en primary key et  int auto-incrémenté. Donc nous n'avons pas besoin de le mentionner. En utilisant t.references, nous allons créer automatiquement un champs "nomtable_id".

class CreateStatuts < ActiveRecord::Migration
  def self.up
    create_table :statuts do |t|
      t.references :membres
      t.string :message
      t.timestamps
    end
  end

  def self.down
    drop_table :statuts
  end
end

 

t.timestamps est un helper qui va permettre de créer 2 champs "created_at" et "updated_at" de type DATETIME qui seront automatiquement renseignés. Nous abandonnons donc notre champ "date_envoi".

 

On fait la même chose pour les autres tables:

002_create_membres.rb

Nous allons encore modifier le schéma de la base de données.

Nous mettrons un id auto-incrémenté pour la table membres et un champs username pour son pseudo.

Ce qui nous donne la configuration suivante:

class CreateMembres < ActiveRecord::Migration
  def self.up
    create_table :membres do |t|
      t.string :username
      t.string :pass
      t.string :email
      t.string :avatar
      t.string :site
      t.integer :etat
      t.timestamps
    end
  end

  def self.down
    drop_table :membres
  end
end

 

Puis la dernière table:

003_create_follows.rb

 

class CreateFollows < ActiveRecord::Migration
  def self.up
    create_table :follows, :id => false do |t|
      t.integer :membres_follower
      t.integer :membres_followed
    end
    execute "ALTER TABLE `follows` ADD PRIMARY KEY ( `membres_follower`, `membres_followed` )"
    add_index :statuts, :membres_id
  end

  def self.down
    drop_table :follows
  end
end

Nous avons ajouté des index pour les clés étrangères et ajouté les clés primaires.

Nous pouvons maintenant générer nos tables !

4) Génération des tables

Ouvrez votre console Ruby, rendez-vous à la base de votre application, puis tapez:

rake db:migrate --trace

Cette commande permet d'exécuter la création des tables et de tout ce qui se trouve dans les fichiers de migration.

Vérifiez que tout se soit bien passé dans votre console et allez faire un tour sur phpMyAdmin voir si vos 3 tables (+ 1 table) sont bien présentes.

Finalement, il y'a quand même plusieurs changement dans la BDD.

Voici le schéma de la BDD mis à jour:

Schéma MySQL Twitterails mis à jour

 

5) Associations entre les tables

Bon maintenant que nos tables sont créées, nous allons devoir indiquer les relations entre les tables (Cardinalités) aux modèles.

Quelles sont les relations entre nos tables:

  • Entre la table statuts et membres: Un statut est posté par un membre et un membre peut poster plusieurs statuts.
  • Entre la table membres et follows: Un membre peut follow plusieurs membres et être suivi par plusieurs membres.

Rails permet de représenter facilement ces relations dans les fichiers models, en utilisant l'un des mots clés suivants:

  • belongs_to
  • has_one
  • has_many
  • has_many :through
  • has_one :through
  • has_and_belongs_to_many

Pour comprendre chacune des relations, je vous invite à vous rendre sur la doc rails.

Rendez-vous maintenant dans les fichiers models pour compléter les relations:

statut.rb

Relation simple avec les membres, un statut appartient à un membre.

class Statut < ActiveRecord::Base
  belongs_to :membre
end

follow.rb

Une instance de Follow référence deux entitées Membre, on a donc 2 belongs_to.

class Follow < ActiveRecord::Base
  belongs_to :follower, :class_name => "Membre", :foreign_key => "membres_follower"
  belongs_to :followed, :class_name => "Membre", :foreign_key => "membres_followed"
end

:foreign_key permet de déterminer à quel attribut du modèle Follow nous devrons associer la liaison au modèle Membre.

:class_name permet de déterminer le modèle à associer, dans notre cas, le modèle Membre.

Vous remarquerez aussi que l'on donne un nom à nos associations: follower et followed.

membre.rb

Nous allons utiliser un "has_many" vers le modèle statut pour dire qu'un membre peut avoir posté plusieurs statuts.

class Membre < ActiveRecord::Base
  has_many :statut

  # les Follows où ce membre est le Follower (1)
  has_many :follows_as_follower, :class_name => "Follow", :foreign_key => "membres_follower"
  # les Membres que ce Membre suit (2)
  has_many :followed, :through => :follows_as_follower 

  # les Follows où ce membre est le Followed (1)
  has_many :follows_as_followed, :class_name => "Follow", :foreign_key => "membres_followed" 
  # les Membres qui sont suivis par ce Membre (2)
  has_many :followed_by, :through => :follows_as_followed, :source => :follower 
end

C'est plutôt complexe, en gros, nous voulons récupérer à la fois le modèle Follow associé et les membres qui suivent le membre ainsi que les membres suivis par ce dernier.

(1) Nous créons l'association avec le modèle Follow en utilisant un has_many.

(2) Nous créons l'association permettant de récupérer les membres suivis et qui suivent le membre en utilisant un has_many :through.

has_many :through va permettre d'aller chercher les membres en passant par le Modèle Follow.

 

Je n'ai pas encore testé les modèles, nous le ferons dans l'étape suivante, un bon moyen pour apprendre à tester la cohérence de nos associations. Si vous pensez que j'ai pu me tromper dans les modèles, n'hésitez pas à me le faire savoir en commentaire, c'est fort possible !

 

Fin de la partie 3 du tutorial

Voilà, tous nos modèles et notre base de données sont correctement configurés.

Prochaine étape, test de notre modèle puis la partie C de MVC, le Controlleur !

Nous verrons comment générer un controlleur, et comment ça fonctionne !

 

N'hésitez pas à apporter vos commentaires et questions si vous en avez.

 

PS: Merci à Vincent P. et Taum pour leur patience et leur aide !

Baraguiné par myosotis le 29/06/09 à 17h50
myosotis sur La Ferme du Web
Salut
Je débute avec rails et j'ai hate de lire la suite. C'est pour quand la quatrième partie qui traite du Controlleur?
Baraguiné par le 20/12/09 à 11h11
Hé pour quand la suite ????
merci
Baraguiné par Nicolas le 05/02/11 à 06h35
Nicolas sur La Ferme du Web
Je ne pensais pas que RoR était aussi complet.
Ca vaut quoi niveau performance ?

Ajouter un Commentaire

Pour poster un commentaire, vous devez être identifié. Vous pouvez choisir parmi ces trois méthodes d'identification:

Compte la Ferme du Web

Identifiez-vous
Inscrivez-vous

Compte Facebook

Connexion avec Facebook

Compte Twitter

Connexion avec votre compte twitter
Rechercher sur la Ferme du web