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