Rail 3.2 :Enchaîner des scopes lambda ?
-
12-12-2019 - |
Question
Dans mon application Rails 3.2.8, j'ai des étendues nommées que j'aimerais enchaîner dans certaines circonstances.
Ainsi, par exemple, j'ai ces deux étendues :
scope :by_status, lambda { |status| if status == "All" then WorkRequest.all else WorkRequest.find_all_by_status(status) end }
scope :in_date_range, lambda { |start_date, end_date| includes([:person, :pier_module]).where("(status_date >= ?) AND (status_date <= ?)", start_date, end_date) }
Je les utilise séparément, mais j'aimerais aussi pouvoir les appeler ensemble comme ceci :
WorkRequest.by_status("Accepted").in_date_range("2012-01-01", "2012-10-02")
Quand j'essaye, il se plaint que in_date_range n'est pas une méthode de Array.
Mais j'ai une autre portée,
scope :active, includes([:person, :pier_module]).where("status = 'New Request'")
et si je le fais
WorkRequest.active.in_date_range("2012-01-01", "2012-10-02")
Ça marche!Apparemment, la portée active renvoie une relation, tandis que les portées lambda renvoient des tableaux et ne peuvent donc pas être chaînées.
J'aimerais savoir pourquoi il y a une différence entre les portées plus simples et les portées lambda, comment les paramètres l'affectent et si je peux faire autre chose que d'écrire une portée combinée, ce que j'ai fait.
scope :by_status_in_date_range, lambda { |status, start_date, end_date| includes([:person, :pier_module]).where("(status = ?) AND (status_date >= ?) AND (status_date <= ?)", status, start_date, end_date) }
Fonctionne, mais pas très SEC (puisque j'ai aussi besoin des oscilloscopes individuels) ou Rails-ish.En cherchant ici et ailleurs, j'ai vu des questions similaires mais aucune ne semble s'appliquer à cette situation, où j'essaie de chaîner deux lambdas avec des paramètres.
La solution
Cela arrive parce que dans votre champ d'application
scope :by_status, lambda { |status| if status == "All" then WorkRequest.all else WorkRequest.find_all_by_status(status) end }
méthodes all
et find_all_by_status
Retour Array
au lieu de ActiveRecord::Relation
.Tu devrais le remplacer par where
Par exemple.
scope :by_status, lambda { |status| where(:status => status) unless status == "All" }