75 votes

Rails ActiveRecord : jointures avec LEFT JOIN au lieu de INNER JOIN

J'ai ce code

User.find(:all, :limit => 10, :joins => :user_points,
                :select => "users.*, count(user_points.id)", :group =>
                "user_points.user_id")

qui génère le sql suivant

SELECT users.*, count(user_points.id) 
FROM `users` 
INNER JOIN `user_points` 
ON user_points.user_id = users.id 
GROUP BY user_points.user_id 
LIMIT 10

Est-il possible de faire un LEFT JOIN au lieu d'un INNER JOIN d'une autre manière que la suivante User.find_by_sql et de taper manuellement la requête ?

85voto

Kylo Points 1423

Vous pouvez essayer ceci

User.find(:all, limit: 10,
            joins:  "LEFT JOIN `user_points` ON user_points.user_id = users.id" ,
            select: "users.*, count(user_points.id)", 
            group:  "user_points.user_id")

0 votes

Super, exactement ce que je cherchais

0 votes

C'est bon, mais à quoi Jakub s'attend-il vraiment avec ça ? Des utilisateurs sans points ? Si c'est le cas, je pense qu'il faut un WHERE user_points.user_id IS NULL Non ?

0 votes

@Kylo existe-t-il une construction dans rails pour créer la jointure gauche sans avoir à taper une chaîne de caractères ?

40voto

8bithero Points 581

Juste pour une référence future, ajouter :all donne un message déprécié. Dans les versions ultérieures de rails, vous pouvez simplement enchaîner les méthodes comme ceci :

User.joins("LEFT JOIN `user_points` ON user_points.user_id = users.id").select("users.*, count(user_points.id)").group("user_points.user_id")

OU utiliser un portée comme ça :

scope :my_scope_name_here, -> { 
        joins("LEFT JOIN `user_points` ON user_points.user_id = users.id")
        .select("users.*, count(user_points.id)")
        .group("user_points.user_id")
}

Vous pouvez également enchaîner .where entre les .join et le .select . J'espère que cela aidera quelqu'un à l'avenir.

16voto

Santosh Points 6791

Rails 5 dispose d'un joints_de_gauche méthode. Vous pouvez donc faire

User.left_outer_joins(:user_points)

ou utiliser l'alias

User.left_joins(:user_points)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X