Active Record : relations entre les tables
CHAPITRE 18 365
© 2007 Groupe Eyrolles
En observant cette migration, on comprend pourquoi il est difficile pour Active Record de
déterminer la nature des relations entre deux tables. Les clés étrangères sur les tables
orders
et
products
sont déclarées de façon identique. Pourtant la colonne
product_id
est utilisée pour
associer un item de la commande avec exactement un produit, alors que la colonne
order_id
est utilisée pour associer plusieurs items du panier avec une seule commande. Autrement dit,
un item du panier est une partie de la commande mais référence précisément un produit.
Cet exemple montre également les conventions de nommage adoptées par Active Record. Les
clés étrangères doivent être baptisées d’après le nom de la classe de la table cible, nom
converti en lettres minuscules et complété par le suffixe
_id
. Il est à noter que, dans ces condi-
tions, le nom de la clé étrangère sera toujours différent du nom de la table référencée. Si vous
utilisez un modèle Active Record nommé
Person
, il sera mis en correspondance avec la
table
people
en base de données. Une clé étrangère, dans une autre table, référençant la
table
people
portera le nom de colonne
person_id
.
Un autre type de relation concerne le cas où un certain nombre d’objets sont liés à un certain
nombre d’autres (par exemple, des produits qui appartiennent à plusieurs catégories et des
catégories qui peuvent contenir plusieurs produits). SQL veut que ce type de relation soit géré
dans une troisième table appelée table de jointure. La table de jointure contient une clé étran-
gère vers chacune des tables concernées. Ainsi, chaque enregistrement de la table de jointure
représente un lien entre les deux tables. Observons cette autre migration :
Rails suppose que le nom de la table de jointure est composé du nom des deux tables jointes classés
par ordre alphabétique. Ainsi, Rails s’attend à ce que la table de jointure des tables
categories
et
def self.up
create_table :products do |t|
t.column :title, :string
# ...
end
create_table :categories do |t|
t.column :name, :string
# ...
end
create_table :categories_products, :id => false do |t|
t.column :product_id, :integer
t.column :category_id, :integer
end
# Les index sont importants pour la performance
add_index :categories_products, [:product_id, :category_id]
add_index :categories_products, :category_id
end