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.

Était-ce utile?

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" }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top