sélectionnez beaucoup à travers de nombreux types de ...
-
21-08-2019 - |
Question
Ceci est mon premier post sur la pile, donc s'il vous plaît garder avec moi si je contrevenais un protocole.
Je travaille sur un projet Rails (2.1.2), et j'ai un scénario de relations qui ressemble à ceci:
event [has_many] days
Les gens (dans différentes catégories) peuvent vous inscrire pour les jours de l'événement, ce qui donne les résultats contraignants suivants:
category [has_many] customers [has_many] orders [has_many] days
[belongs_to] event
Maintenant, je voudrais avoir le nombre total des « événements » pour un client, ou pour tous les clients dans une certaine catégorie, et je suis coincé. Autant que je sache, il n'y a aucun moyen d'effectuer une simple « découverte » par un tableau d'objets, correct? Alors, quelle serait la solution; boucles imbriquées, et une méthode Collect pour obtenir les « événements » des « jours » dans les commandes?
S'il vous plaît laissez-moi savoir si je suis pas clair.
Merci pour votre aide!
La solution
Personnellement, je le faire en utilisant une instruction MySQL. Je ne suis pas sûr, mais je pense qu'il est beaucoup plus rapide que les autres exemples (en utilisant les rails prévus méthodes d'association).
Cela signifie que dans le modèle client que vous pourriez faire quelque chose comme: (Notez que je suppose que vous utilisez les clés d'association par défaut: « model_name_id »)
class Customer
def events
Event.find_by_sql("SELECT DISTINCT e.* FROM events e, days d, orders o, customers c WHERE c.id=o.customer_id AND o.id=d.order_id AND e.id=d.event_id")
end
end
qui renvoie tous les événements associés à l'utilisateur, et pas dupliqué (le mot-clé 'DISTINCT fait sûr de cela). Vous, comme dans l'exemple ci-dessus, perdre des informations sur les jours exactement l'utilisateur signé pour. Si vous avez besoin de cette information, s'il vous plaît dire.
En outre, je n'ai pas inclus un exemple pour votre modèle de catégorie, parce que je suppose que vous pouvez adapter mon exemple vous. Sinon, me le faire savoir.
EDIT:
Je viens de lire que vous voulez juste compter les événements. Cela peut être fait encore plus rapide (ou du moins, moins gourmande en mémoire) en utilisant l'instruction de comptage. Pour utiliser cela, il suffit d'utiliser la fonction suivante:
def event_count
Event.count_by_sql(SELECT DISTINCT COUNT(e.*) FROM ... ... ...
end
Autres conseils
Vos modèles ressemblent probablement comme ceci:
class Category
has_many :customers
class Customer
has_many :orders
has_many :days, :through => :orders # I added this
belongs_to :category
class Order
has_many :days
belongs_to :customer
class Day
belongs_to :event
belongs_to :order
class Event
has_many :days
Avec cela, vous pouvez compter les événements pour le client:
events = customer.days.count(:group => 'event_id')
Il retournera OrderedHash comme ceci:
#<OrderedHash {1=>5, 2=>13, 3=>0}>
Vous pouvez obtenir compter des événements par:
events[event_id]
events[1] # => 5
events[2] # => 13
etc.
Si vous voulez nombre total d'événements uniq:
events.size # => 3
Dans le cas des événements comptant pour tous les clients dans la catégorie que je ferais quelque chose comme ceci:
events = {}
category.customers.each {|c| events.merge!(c.days.count(:group => 'event_id') ) }
events.size # => 9 - it should be total number of events
Mais dans ce cas, vous perdez des informations combien de fois chaque événement est apparu.
Je n'ai pas testé cela, donc il pourrait y avoir quelques erreurs.