Il est assez simple d'extraire des données de plusieurs tables liées par des clés étrangères en utilisant le langage SQL brut. Je peux le faire, par exemple :
SELECT title, domestic_sales
FROM movies
JOIN boxoffice
ON movies.id = boxoffice.movie_id;
Cela me donnerait un tableau avec deux colonnes : title
y domestic_sales
où les données de la première colonne proviennent du tableau movies
et les données de la deuxième colonne proviennent du tableau boxoffice
.
Comment puis-je faire cela dans Rails en utilisant du code Ruby ? Je peux, bien sûr, obtenir le même résultat si j'utilise du SQL brut. Ainsi, je pourrais faire ce qui suit :
ActiveRecord::Base.connection.execute(<<-SQL)
SELECT title, domestic_sales
FROM movies
JOIN boxoffice
ON movies.id = boxoffice.movie_id;
SQL
Cela me donnerait un PG::Result
avec les données que je veux. Mais c'est super inélégant. J'aimerais pouvoir obtenir ces informations sans utiliser le SQL brut.
Donc, la première chose qui me vient à l'esprit est :
Movie.select(:name, :domestic_sales).joins(:box_office)
Le problème, cependant, c'est que la ligne de code susmentionnée renvoie un groupe de Movie
objets. Puisque le Movie
ne dispose pas de la classe domestic_sales
attribut, je n'ai pas accès à cette information.
La prochaine chose à laquelle j'ai pensé est d'utiliser une boucle. Donc, je pourrais faire quelque chose comme :
Movie.joins(:box_office).to_a.map do |m|
{name: m.name, rating: m.box_office.domestic_sales}
end
Cela me donne exactement les données que je veux. Mais cela coûte n + 1 requêtes SQL, ce qui n'est pas bon. Je devrais être capable d'obtenir ceci avec une seule requête...
Alors : Comment puis-je récupérer les données que je veux sans utiliser le SQL brut et sans utiliser des boucles qui coûtent plusieurs requêtes ?