20 votes

Rails named_scopes avec jointures

J'essaie de créer un named_scope qui utilise une jointure, mais bien que le SQL généré semble correct, le résultat est nul. Par exemple :

class Clip < ActiveRecord::Base      
  named_scope :visible, {
    :joins => "INNER JOIN series ON series.id = clips.owner_id INNER JOIN shows on shows.id = series.show_id", 
    :conditions=>"shows.visible = 1 AND clips.owner_type = 'Series' "
  }

(Un clip appartient à une série, une série appartient à un spectacle, un spectacle peut être visible ou invisible).

Clip.all le fait :

SELECT * FROM `clips` 

Clip.visible.tout fait :

SELECT * FROM `clips` INNER JOIN series ON series.id = clips.owner_id INNER JOIN shows on shows.id = series.show_id WHERE (shows.visible = 1 AND clips.owner_type = 'Series' ) 

Ça a l'air bien. Mais le tableau de modèles de clips qui en résulte comprend un clip dont l'identifiant ne se trouve pas dans la base de données - il a pris l'identifiant d'une émission à la place. Où est-ce que je me trompe ?

26voto

Ben Scofield Points 4950

Le problème est que la requête "SELECT *" récupère toutes les colonnes des clips, des séries et des émissions, dans cet ordre. Chaque table a une colonne id, et il en résulte des conflits entre les colonnes nommées dans les résultats. La dernière colonne id récupérée (celle des émissions) remplace celle que vous voulez. Vous devriez utiliser une option :select avec les :joins, par exemple :

named_scope :visible, {
  :select => "episodes.*",
  :joins => "INNER JOIN series ON series.id = clips.owner_id INNER JOIN shows on shows.id = series.show_id", 
  :conditions=>"shows.visible = 1 AND clips.owner_type = 'Series' "
}

5voto

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