Dans mon Rails 4 projet d'application (modèle) has_many
Vidéos (modèle). J'ai une portée nommée dans le modèle de vidéos:
scope :live, where( is_deleted: 0, sent_to_api: 1 )
Dans l'une de mes vues de projet, je fais cela (le projet est une instance de Project):
project.videos.live.size
Ce que je m'attends à obtenir, c'est le nombre de projets dans ce projet spécifique mais à la place j'obtiens le nombre de vidéos dans tout projet . C'est comme si .live
ne renvoie pas un sous-ensemble de .videos
mais plutôt le remplacer.
Je vois que cela explique ici que le chaînage d'étendues nommées les unes avec les autres doit être combiné avec un ET logique mais lorsqu'il est appliqué à une "méthode d'association" [<- je ne suis pas sûr de la terminologie appropriée pour .videos
dans ce contexte] cela ne semble pas se produire.
Quelle est la bonne façon de procéder?
Je crois qu'il devrait se lire comme ceci dans Rails 4:
scope :live, -> { where(is_deleted: 0, sent_to_api: 1) }
Les documents Rails 4 et tous les exemples qu'il contient vous montrent comment passer un objet appelable à la portée pour vous assurer qu'il est appelé à chaque fois. Si cela ne fonctionne pas comme cela, essayez de l'implémenter en tant que classe méthode et voyez comment cela fonctionne pour vous.
http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html
J'irais simplement pour les méthodes de classe et laisserais les portées derrière. La syntaxe est beaucoup plus simple car elle ressemble à n'importe quelle autre méthode de classe, y compris en lui passant des paramètres.
Essayer:
def self.live
where( is_deleted: 0, sent_to_api: 1 )
end
Puis:
project.videos.live.size
et voyez si ça aide.
Pour plus d'informations, lisez ici .