Question à 100 piasses : Qui aime écrire du SQL ?
Ceux qui ont répondu OUI peuvent s'en aller :D

En effet que ce soit à la création ou au traitement de vos données, vous n'écrirez pratiquement jamais de SQL avec Rails.
Mais alors comment on les crée nos bases ?

La réponse de Rails s'appelle les migrations.
Quand vous voulez créer une nouvelle table, vous créez (ou faite faire à Rails) une nouvelle migration, celle-ci comporte deux méthodes "up" et "down".

De cette manière, il sera aisé pour Rails de revenir en arrière si finalement votre implémentation de la base ne vous plait pas.

La création de ce modèle s'écrira : (à exécuter en console ou dans l'interface de votre IDE)

script/generate model Student firstname:string lastname:string date_of_birth:date section:string promotion_id:integer

On précise que l'on veut créer un modèle, on donne ensuite son nom, puis les colonnes de la base de données avec leur types.

En exécutant ceci, vous créer tous les fichiers de votre modèle dont une migration ressemblant à ceci, dans le up, on crée notre table, dans le down on la supprime.

class AddStudents < ActiveRecord::Migration
    def self.up
      create_table :students do |t|
        t.string        :firstname
        t.string        :lastname
        t.date          :date_of_birth
        t.string        :section
        #S pour Scientifique, L pour Littéraire, ES pour Economique et Social
        t.integer       :promotion_id  
        t.timestamps
      end
    end

    def self.down
      drop_table :students
    end
  end

Plutôt simple n'est-ce pas ? Et avec ça Rails s'adaptera à votre base de données, qu'elle soit Mysql, Postgresql, Oracle, SQLite...

Et si demain vous changez Mysql pour Postgres, il suffira de faire un petit

rake db:migrate

pour récréer toutes vos tables (En réalité, Ruby éxécutera à la suite toutes les méthodes up de vos migrations).

Vous aurez surement remarqué le promotion_id, on supposera dans ce tutorial que l'on a ailleurs une table Promotion avec notamment l'année de la promo et que ce champ servira à faire le lien entre un étudiant et sa promotion.

Ok, mais cette liaison elle est définie où ? On a pas écrit les contraintes dans notre SQL là ?
Oui c'est vrai, allons donc modifier nos modèles pour changer ça. Et puisque nous y somme, nous indiquerons qu'un étudiant doit forcément avoir un nom et un prénom (lignes not null en quelque sorte)

class Promotion < ActiveRecord::Base
    has_many :students
end

class Student < ActiveRecord::Base
    belongs_to :promotion
    validates_presence_of :firstname
    validates_presence_of :lastname
  end

Difficile de faire plus clair non ?

Oui mais dans le code après comment ça se passe ?

Imaginez que vous souhaitiez récupérer tous les étudiants (en gros un SELECT * FROM students)
vous ferez simplement

Student.all

Si vous voulez récupérer la ligne correspondant à la promotion de 2006 :

promo_2006 = Promotion.find_by_year(2006)

Les étudiants de cette promo :

promo_2006.students

Allez compliquons un peu, il n'y a pas de where, pas de conditions dans nos requête actuelles, ajoutons les :

Disons que l'on ne veut récupérer que les étudiants Scientifiques.
Ajoutons à notre modèle la ligne suivante :

named_scope :scientists, :conditions => {:section => "S"}

En francais : on nommera "scientists" les étudiants ayant comme section "S"
On peut désormais écrire

Student.scientists

pour récupérer tous les étudiants scientifiques

Ces named_scope sont géniaux, ajoutons-en deux pour trouver les étudiant majeurs et mineurs.

named_scope :majors, :conditions => ['date_of_birth < ?', 18.years.ago]
named_scope :minors, :conditions => ['date_of_birth > ?', 18.years.ago]

On peut maintenant faire dans tous nos Controllers :

Student.majors

Pour récupérer les étudiants majeurs.

Et si l'on veut, dans la promo 2006, les étudiants à la fois majeurs et scientifiques :

promo_2006.students.majors.scientists

Et le tour est joué !
Incroyable non ? (qui me l'écrit en SQL avec la jointure et tout et tout ?)

C'est le moment de citer DHH :

Beautiful code makes happy programmers.
David Heinemeier Hansson, Créateur de Rails

Voilà pour les requêtes, pour créer un enregistrement, c'est tout aussi simple :

jb = Student.create(:firstname => "Jonathan", :lastname => "Blanchet")

La création précédente fonctionnera puisqu'elle remplie bien les conditions décrites précédemment (un étudiant à forcément un nom et un prénom).

Allez un dernier exemple pour la route, imaginez que la personne utilisant cette application souhaite, dans l'interface de création des utilisateurs, pouvoir les lier à une promotion en tapant simplement l'année de celle-ci.

Côté modèle, cela veut dire qu'il va falloir trouver la promotion si elle existe, la crée sinon.

Une fois traduit en Rails cela donne :

Promotion.find_or_create_by_year(params[:year])

Simple non :)

Allez je vous attend pour la suite, on verra le rôle du Controller.

Les autres articles :

Ruby, c'est quoi comme langage ?
Un peu de syntaxe Ruby...
Rails, la locomotive de Ruby !
ActiveRecord : Vos données, c'est mon dada.
ActionController : Monsieur Circulation
ActionView : Imprimeur de son état