2010-06-08 3 views
0

comment puis-je écrire un NOT IN dans la syntaxe de portée nommée? Par exemple, l'utilisateur: has_many Photos, comment puis-je définir:nommé scoped NOT IN, comment?

User.has_no_photo 

et retourne tous les utilisateurs qui ne sont pas dans le modèle Photo? Merci!

Répondre

0
named_scope :has_no_photos, :conditions => [ 
    "id NOT IN ?", 
    Photo.all(:select => "distinct user_id").map(&:user_id).map(&:to_i) 
] 

Je suppose que vous avez une norme « Photo.belongs_to: l'utilisateur "association, et touches entières

+1

Cela donnera une erreur - NoMethodError: méthode non définie 'user_id' pour Fixnum. Vous vouliez probablement mapper 'to_i' après' user_id' (ou omettre complètement la seconde carte ...) –

+0

Ouais, merci, corrigé –

+0

'" id NOT IN? "' Devrait être '" id NOT IN (?) "' – ohho

0

ActiveRecord ne diffère pas de ce que vous feriez dans SQL:

class User < ActiveRecord::Base 
    has_many :photos 
    named_scope :has_no_photos, 
    :conditions => "(SELECT COUNT(#{Photo.table_name}.*) 
        FROM #{Photo.table_name} 
        WHERE #{Photo.table_name}.user_id = #{User.table_name}.id) = 0" 
end 

Il y a probablement des moyens plus efficaces de le faire. L'une serait de stocker les photos_count sur les lignes d'utilisateur: alors la requête devient simple photos_count = 0, au lieu d'un complexe rejoindre:

class Photo < ActiveRecord::Base 
    belongs_to :user, :counter_cache => true 
end 

class User < ActiveRecord::Base 
    has_many :photos 
    named_scope :has_no_photos, :conditions => {:photos_count => 0} 
end 
+0

mauvais exemple. –

+0

Ils sont généralement assez cohérents pour la plupart des cas. C'est votre travail en tant que dev pour assurer qu'ils restent cohérents. –