2009-06-10 5 views
0

Un projet a 3 tables: clients, factures, livraisonsComment utiliser les rails pour trouver ce résultat sur 3 tables?

Les relations sont:

   client has_many invoices 
      client has_many deliveries 


       invoices belongs_to client 
       deliveries belongs_to client 

Les deux modèles de factures et livraisons ont un champ de date. Maintenant, je veux trouver tous les clients qui ont au moins 1 dossier soit dans les factures ou les livraisons dans ce mois, de sorte que les clients distincts qui ont des enregistrements dans les factures ou avoir des dossiers dans les livraisons ou même les deux. Comment trouver les clients utilisant Rails ou même SQL?

Merci pour l'aide

Répondre

1

ce serait ma première fissure à elle:

Client.all(:include => [:deliveries, :invoices], :conditions => ['(deliveries.date > :start_date) OR (invoices.date > :start_date)', :start_date => 1.month.ago]) 

Idéalement je voudrais utiliser la méthode de named_scope ou finder sur mesure dans le modèle pour gérer ceci:

class Client < ActiveRecord::Base 
    named_scope :active_since, lambda {|date| {:include => [:deliveries, :invoices], :conditions => ['(deliveries.date > :start_date) OR (invoices.date > :start_date)', :start_date => date]}} 

    # or 
    def self.find_by_delivery_or_invoice_activity 
    all(:include => [:deliveries, :invoices], :conditions => ['(deliveries.date > :start_date) OR (invoices.date > :start_date)', :start_date => 1.month.ago]) 
    end 
end 

Je suis assez sûr que cela devrait être assez proche de ce que vous n eed, mais je ne m'attendrais pas à ce qu'il fonctionne sans quelques modifications pour votre situation.

2

Je définirais une méthode sur le client qui vérifie si date est mois x pour les livraisons et les factures

def has_invoice_in_month(year, month) 
    start_date = Date.new(year, month, 1) 
    end_date = Date.new(year, month, -1) 
    invoices.each do |invoice| 
    return true if start_date < invoice.date and end_date > invoice.date 
    end 
end 

Maintenant, vous itérer sur les clients et les amener tous ensemble

Client.find(:all).collect { |c| c if c.has_invoice_in_month(y,x) or 
c.has_delivery_in_month(y,x))}.uniq 

L'appel uniq supprime tous les objets qui se sont retournés nul et

Si seulement quelques clients sur beaucoup de factures ou de livraisons vous pouvez essayer s'il est plus rapide d'obtenir Client.find (: all,: join =>: factures) + Client.find (: all,: join => : livraisons)

Questions connexes