Ciao,
nel precedente thread ho avuto l’occasione di provare questo codice
class Product < ActiveRecord::Base
quantity:integer
amount:decimal
def self.with_total_amount
select(’*, quantity * amount as total_amount’)
end
def self.sum_of_total_amounts
sum(:total_amount)
end
end
Product.with_total_amount.sum_of_total_amounts
che però non funziona in quanto .sum verifica direttamente se
l’argomento
passatogli è una colonna della tabella, a prescindere dagli alias
precedentemente introdotti.
Sono l’unico che si aspettava che quel codice avrebbe funzionato? ^_^’
Questa versione invece funziona:
def self.sum_of_total_amounts
sum(‘quantity * amount’)
end
Sarebbe sensato che .sum verificasse la presenza di alias creati fino a
quel punto della scope chain in modo da rendersi conto che in (SELECT *,
quantity * amount as total_amount FROM “products”) è presente
l’attributo
sul quale poter wrappare la funzione matematica?
Sarebbe sensato che .sum verificasse la presenza di alias creati fino a
quel punto della scope chain […]
IMHO ActiveRecord wrappa Arel troppo semplicisticamente, castrando
quella
che a mio parere è una libreria fenomenale. Non capisco neanche perché
abbiano definito dei metodi come “sum”, “average” etc. implementandoli
usando Arel “di nascosto” invece che fare dei semplici “syntactic
sugars”
che ti restituiscono la relazione; forse per retrocompatibilità? Non
ricordo neanche se erano definiti in ActiveRecord prima di Arel… mah.
Mi spiego meglio: volendo calcolare la somma del quadrato degli id degli
utenti (vai a capire perchè poi ):
SELECT SUM("users"."id" * "users"."id") AS id_squares_sum FROM
“users”
Usando Arel possiamo comporla in questo modo (a me ricorda molto jQuery
e
mi piace un sacco):
La precendente dichiarazione ha i seguenti problemi:
Bisogna definire una variabile estemporanea per comodità, cosa che
spesso
mi ferma da usare Arel poiché questa cosa mi costringe a rinunciare alla
possibilità del oneline
Bisogna fare un to_aprima della first altrimenti viene lanciata
un’eccezione per un ORDER BY che viene aggiunta a buffo da ActiveRecord,
che ti mette l’ordinamento per id anche in questo caso in cui potrebbe
benissimo sapere che non ce lo deve mettere; cosa che invece
ActiveRecord
ha cura di fixare per la sum di ActiveRecord::Calculations. Questo per
dire
quanto Arel è meno considerato.
A me piacerebbe invece qualcosa più simile a questo: