To ja powiem co wymyśliłem na MySQL’a, aczkolwiek taki to potwór wyszedł, że masakra.
Otóż:
[code=ruby]@work_records = WorkRecord.find_by_sql("
SELECT *, last_name, first_name,
SUM(time) as time_sum, work_records.id as work_record_id
FROM work_records
LEFT JOIN employees ON work_records.employee_id = employees.id
WHERE work_records.date >= ‘#{start_date}’ AND work_records.date <= ‘#{end_date}’
GROUP BY work_records.employee_id ORDER BY employees.last_name ASC;")
@work_records.each { |wr| wr.time = wr.time_sum.to_i }[/code]
Takie coś działa, tylko trzeba później zmieniać sumę ze stringa la liczbę, bo niestety otrzymujemy Stringa.
Działać działa, ale jest paskudne. Szczególnie, że mój WorkTime w rzeczywistości ma około 15 atrybutów, z kótrych każdy musi być zsumowany. Jednym słowem wychodzi jakiś taki potwór na 40 linii…
Ma ktoś pomysł jak to zrobić bardziej Clean Code’owo ??
Jakby kogoś to interesowało, to częściowo sobie poradziłem.
Mianowicie LEFT JOIN zrobiłem tak jakby po staremu ale z nową metodą, czlyli
WorkRecord.select( itd...).joins("LEFT JOIN employees ON employees.id = work_records.employee_id").. itd
Czyli to co po staremu było w parametrze :joins metody find teraz dajemy do joins() i jest ok. zwraca to nam ActiveRecordRelation więc jest Arel’owo pewnie da się to zorbić jeszcze ładniej, ale jak na razie mi się nie udało…
Natomiast mimo wszystko wartości obliczone przez funkcje agregującą SUM, czyli np. SUM(time) as time_sum,
w MySQL zwracane są jako String i trzeba je sobie samemu przekonwertować na odpowiednie typy. To jest trochę (a nawet bardzo denerwujące ), ale nie udało mi się jeszcze znaleźć rozwiązania…
Dodatkowo odryłem, że jeśli mamy w migracjach decimale i nie podamy parametrów :precision i :scale, to w MySQL są one utworzone jako decimal(10,0), więc trzeba też na to uważać…