Tutorial Rubyonrails 3 - Partie 3 - Création des relations entre les models (détail relation et migration)

Partie 3 – Rails3 -  Création des relations entre les models (détail relation et migration)

N’hésitez à mettre des commentaires / à corriger mes fautes / à rajouter des choses !

Rails intègre un système de migration. Chaque migration et un fichier ruby qui modife la structure de la base de données.

Donc si vous avez besoin de renommer un champ, de rajouter une table, de rajouter un champ, de supprimer un champ vous devez créer une migration.

Les migrations se trouvent dans monblog/db/migrate . Vous devez en avoir 3, car rails generate model crée une migration pour rajouter une table dans la base de données.

Pourquoi parler des migrations ?

Eh bien, nous avons les models, nous savons les manipuler. Mais ActiveRecord est encore un peu plus puissant, il gère les relations entre les models pourvu que nous suivions les conventions !

Souvenez-vous dans la partie 2 :

reader : celui qui laissera un ou plusieurs comments sur un post.
post : un article du blog, il possède plusieurs comments.
comment : les commentaires des readers sur un post.

Nous allons donc créer une migration pour ajouter les clés étrangères oubliées  (volontairement) lors du rails generate model.

Donc créons une migration pour ajouter les clés étrangères:
rails generate migration add_foreign_keys

Ouvrons le fichier (monblog/db/migrate/XXXXXXXXXXXXX_add_foreign_keys.rb):

class AddForeignKeys < ActiveRecord::Migration
 def self.up
   #On met ici le code pour passer à un nouveau schéma de la base de données
 end

 def self.down
   #On met ici le code pour passer à la version précédente du schéma de la base de données
 end
end

Exemple :
On peut ajouter une colonne / supprimer une colonne / renommer une colonne
Attention les tables sont toujours au pluriel !
- Les noms de table correspondent aux noms des models au pluriel
- Les noms des tables de jointure (has_and_belongs_to_many) se nomment suivant cette convention : nom des models au pluriel par ordre alphabétique séparés par un underscore _ .

add_column ‘ma_table_au_pluriel’, ‘mon_champ’, :type
remove_column ‘ma_table_au_pluriel’, ‘mon_champ’
rename_column ‘ma_table_au_pluriel’, ‘ancien_nom’, ‘nouveau_nom’

Les types disponibles sont les mêmes que dans la partie précédente du tutorial.

Un peu de lecture
https://guides.rubyonrails.org/migrations.html

Par convention les clés étrangères se notent : model au singulier + “_id”, donc pour notre blog:

class AddForeignKeys < ActiveRecord::Migration
 def self.up
   #On met ici le code pour passer à un nouveau schéma de la base de données
   add_column ‘comments’, ‘post_id’, :integer
   add_column ‘comments’, ‘reader_id’, :integer
 end

 def self.down
   #On met ici le code pour passer à la version précédente du schéma de la base de données, donc l’inverse de ce qu’il y a dans up
   remove_column ‘comments’, ‘post_id’
   remove_column ‘comments’, ‘reader_id’
 end
end

Puis on applique les changements au schéma de base de données

rake db:migrate

Pour revenir en arrière d’une migration : rake db:rollback, mais ne le faites pas.

Maintenant il faut dire à rails qu’il existe des relations entre nos models. Il existe plusieurs types de relation gérés dans les models :

  • belongs_to
  • has_one
  • has_many
  • has_many :through
  • has_one :through
  • has_and_belongs_to_many (suivez les conventions pour créer la table de jointure : noms des tables au pluriel par ordre alphabétique séparés par _ )


Je vous (oblige / conseille fortement) de lire en anglais (mais c’est facile à comprendre) :
https://guides.rubyonrails.org/association_basics.html#the-types-of-associations

Pour nous :

Model Post :
Un article  à plusieurs commentaires

class Post < ActiveRecord::Base
 #Remarquez le pluriel (avec le "s" à comments)
 has_many :comments

 # Méthode d’instance qui renvoie le nombre de commentaires
 def nb_comment
   return self.comments.length
 end

 # Méthode de classe (précédé de self. ) qui affiche “Méthode de classe”
 def self.nb_post
   return Post.all.length
 end
end

Model Comment :
Un commentaire appartient à un article et est écrit par une personne

class Comment < ActiveRecord::Base
 #Remarquez le singulier
 belongs_to :post
 belongs_to :reader
end

Model Reader :
Un lecteur du blog peut écrire plusieurs commentaires

class Reader < ActiveRecord::Base
 #Remarquez le pluriel (avec le "s" à comments)
 has_many :comments
end

Maintenant, rails connait les relations, nous pouvons donc manipuler les objets comme ceci :
Vous pouvez tester en console (rails console ou rails c) !

post = Post.new(:title => ‘titre 1’)
post.save

reader = Reader.new(:pseudo => ‘rivsc’)
reader.save

comment = Comment.new(:content => ‘Mon commentaire 1’)
#Grace aux relations
comment.reader = reader
comment.post     = post
comment.save

#Renvoie le pseudo de la personne qui a mis le “Mon commentaire 1”
comment.reader.pseudo

comment = Comment.new(:content => ‘Mon commentaire 2’)
#Grace aux relations
comment.reader = reader
comment.post     = post
comment.save

#remarquez le pluriel, car le post peut avoir plusieurs commentaires (has_many :comments)
#Ceci renvoie un tabeau avec les commentaires associés au post
#nous voilà presque débarrassés de sql :-p
post.comments

Un peu de lecture : https://guides.rubyonrails.org/migrations.html

Prochainement Partie 4 – ActiveRelation et scopes