Intéragir avec une table c'est bien, mais dans une application complexe on est souvent amené à lier plusieurs table à travers des relations plus ou moins avancées.
Relation 1..n
On va commencer par la relation la plus courante, la relation belongsTo / hasMany. Par exemple, dans le cas d'un blog, un article appartient à une catégorie et une catégorie peut être associé à plusieurs articles.
Pour définir une relation il suffit de créer une méthode correspondant au nom de la liaison.
class Post extends Model{
public function category(){
return $this->belongsTo('App\Category');
}
}
Pour associer les catégories aux articles il faudra utiliser la méthode hasMany()
class Category extends Model{
public function posts(){
return $this->hasMany('App\Post');
}
}
Une fois cette relation établie il est alors possible de récupérer les informations simplement depuis un model.
$post = Post::first();
$post->category; // Récupère la catégorie
$post->category(); // Récupère l'association
Récupérer l'association peut s'avérer utile, surtout dans le cas d'une relation hasMany()
afin d'effectuer des conditions supplémentaires.
$category = Category::first();
$posts = $category->posts()->where('online', true);
Le problème n+1 requêtes
La logique Active Record permet une approche objet des relations mais peut s'avérer très gourmande pour la base de donnée. En effet, par défaut chaque accès à $post->category
va générer une requête supplémentaire. Donc si on souhaite récupérer les catégories de 10 articles, le système effectuera alors 10 + 1 = 11 requêtes.
Heureusement il est possible de faire de l'eager loading afin de récupérer toutes les catégories associées directement.
$category = Category::first()->with('category');
// Génèrera un SELECT * FROM posts WHERE id IN (...) à l'avance