2010-09-16 14 views
0

Note: J'utilise Rails 2.3.8, pas 3.La meilleure façon de remplacer named_scope pour les associations has_many dans Rails?

J'ai un modèle photo avec un default_scope:

default_scope :conditions => ["published = ?", true], :order => :position 

Calling photo_album.photos renvoie toutes les photos publiées commandées par la position comme il se doit . Cependant, lors de la boucle à travers ces albums photo dans un panneau d'administration pour afficher le nombre de photos dans chaque, les résultats sont erronés:

pluralize(photo_album.photos.count, "photo") 

renvoie 0, comme aucun sont publiées.

Je sais que des questions similaires ont été posées, et la réponse est généralement sur le modèle de "utiliser une méthode de classe with_exclusive_scope". Pour autant que je peux dire, cela empêche complètement l'utilisation des associations standards Rails - essentiellement pour résultat quelque chose comme ceci:

pluralize(Photo.all_photos_in_album(photo_album.id).count, "photo") 

et nécessitant une méthode de classe comme:

def Photo.all_photos_in_album(album_id) 
    self.with_exclusive_scope { find(:all, :conditions => ["photo_album_id = ?", album_id]) } 
end 

juste pour afficher le total nombre de photos dans un album. Cela semble fou - l'annulation de la valeur par défaut ne devrait pas nécessiter l'abandon des conventions d'association Rails. with_exclusive_scope ne peut pas non plus être utilisé dans une méthode d'instance (méthode protégée) - cela m'aurait permis de créer une méthode d'instance PhotoAlbum appelée "all_photos" pour au moins préserver l'apparence des associations (photo_album.all_photos). Mais non, ce n'est pas autorisé :(

A part la suppression default_scopes, qui se sont avérées très utiles sur le site, personne ne sait d'un champs d'application par défaut override façon et maintenir la syntaxe d'association Rails?

Merci!

Edit:

Je liquidée l'ajout d'une méthode d'instance PhotoAlbum que, si ce n'est pas un remplacement de default_scope réelle, fait à faire pour la syntaxe beaucoup plus agréable dans mes vues:

def all_photos_count 
    PhotoAlbum.count_by_sql("SELECT COUNT(id) FROM photos WHERE photo_album_id = #{self.id} ORDER BY created_at") 
end 

pluralize(photo_album.all_photos_count, "photo") 

Bien que ce ne soit pas exactement une association AR has_many et qu'il repose sur du SQL pur, c'est le meilleur compromis que j'ai trouvé jusqu'ici.

Répondre

0

Pour moi , la meilleure solution dans ce cas était d'utiliser ni default_scope ni has_many conditions et de s'en tenir à named_scopes. Deux named_scopes accompli la majeure partie de ce que je devais garder mon point de vue maigre:

named_scope :public_list, :conditions => ["published = ?", true], :order => :position 
named_scope :private_list, :order => "created_at DESC" 
0

Je ne comprends pas pourquoi vous ne le faites pas dans l'album:

has_many :photos 
has_many :published_photos, :class_name => 'Photo', :conditions => ["published = ?", true], :order => :position 

De cette façon, vous pouvez faire:

@album.photos.count 
@album.published_photos 

Et ainsi de suite ...

+0

A l'origine, je l'ai fait quelque chose de similaire à l'aide d'un named_scope appelé: publiée (et non à l'aide d'un default_scope).La raison pour laquelle je n'ai pas suivi cette route est que la demande de photos d'album publiées est beaucoup plus fréquente, je voulais que ce soit la valeur par défaut (à la fois pour réduire le code actuel et minimiser les changements dans le code actuel). default_scope aurait été génial pour ça, mais comme il est devenu comme une paire de chaussures vraiment confortables qui ne se détacheront pas (idéal pour marcher, mauvais pour dormir), je reviendrai peut-être à mon plan original (similaire à votre réponse). – modulaaron