2010-09-09 4 views
0

J'utilise ActiveRecord et Ruby (en dehors de Rails) pour suivre certaines statistiques..Recherche d'une méthode dans ActiveRecord

J'ai ajouté une méthode (total_cost) à l'un de mes modèles pour faire des calculs en utilisant quelques colonnes du modèle courant ainsi qu'une colonne d'un autre modèle. Je voudrais vraiment pouvoir utiliser certaines des provisions d'ActiveRecord pour les maths (moyennage, sommes) et les anciennes trouvailles en utilisant la méthode que j'ai définie, mais toute tentative pour le faire me met (parfaitement compréhensible) 'Unknown erreur de colonne, par exemple

Article.find(:all, :conditions => ["total_cost > ?", 300])

En conséquence, je fais des choses d'une manière que nous pourrions qualifier de brute-Forcey, juste de trouver tous les articles puis bourrer la total_value de chacun dans un tableau et de faire des sommes et moyennes avec cela.

Est-ce que j'ai d'autres alternatives que ce que je fais? Devrais-je regarder passé ActiveRecord à MySQL lui-même pour calculer les valeurs en question?

Répondre

2

Vous pouvez faire

Article.sum(:total_cost, :conditions => ["total_cost > ?", 300]) 
Article.average(:total_cost, :conditions => ["total_cost > ?", 300]) 

Compte tenu total_cost est une méthode:

total_cost = 'freelance_cost + effort * editor.hourly_rate' 
Artice.sum(total_cost, :conditions => ["#{total_cost} > ?", 300], :joins => [:editor]) 
+0

Je ne peux pas le faire. 'total_cost' n'est pas une colonne dans la table article. C'est une méthode que j'ai écrite qui somme le 'freelance_cost' et le produit de' effort' et 'Article.editor.hourly_rate'. Quand j'essaie la syntaxe suggérée dans irb, j'obtiens: 'ActiveRecord :: StatementInvalid: Mysql :: Error: colonne inconnue 'total_cost' dans 'liste des champs' – mph

1

Une option est de traduire la façon dont le coût total est calculé dans une expression SQL afin que vous pouvez remplacer cette expression pour toute référence dont vous pourriez avoir besoin pour 'total_cost' dans une requête. Cela pourrait être très lourd si le coût total est compliqué à calculer ou dépend de plusieurs tables.

Si cela est possible, cela semble logique d'avoir un attribut total_cost sur votre modèle Article. Au lieu de faire le calcul lorsque quelqu'un appelle la méthode a.total_cost, vous pouvez le calculer lorsque le modèle change en utilisant un rappel et enregistrez-le ensuite. Par exemple:

def before_save 
    self.total_cost = ... whatever ... 
end 

Cela vous permettrait d'utiliser la somme et de faire la moyenne des coûts totaux. Ce serait beaucoup plus efficace que d'obtenir des articles, de calculer le coût total pour chacun d'entre eux, puis de les agréger. Il serait probablement aussi plus efficace que de le calculer chaque fois qu'il est demandé.

Cette solution dépend de la valeur pour le coût total ne changeant pas un lot. S'il change tout le temps en fonction de différents objets changeant, il sera plus difficile de détecter quand le coût total doit changer et moins efficace pour le calculer de cette manière. Cela rendrait certainement vos calculs plus faciles.

1

find méthode crée SQL. Vous ne pouvez pas utiliser la méthode total_cost dedans. Il doit donc écrire le calcul de total_cost dans SQL. Si vous voulez utiliser la méthode, vous pouvez filtrer toutes les données nécessaires.

@articles = Article.find :all 
@articles = @articles.select {|a| a.total_cost > 300} 

Mais cette façon dépense plus de ressources ..

Questions connexes