Mam dwa modele jeden Piece, drugi Profile. Trzeci model (Album)leci jako ‘proxy’.
Zresztą SELECT wszystko rozjaśni.
Chciałbym osiągnać coś w stylu SQLowego w Railsach:
SELECT p.id, p.first_name, p.last_name, COUNT(*) as "piece count"
FROM profiles p
INNER JOIN albums a ON a.profile_id = p.id
INNER JOIN pieces pi ON pi.album_id = a.id
GROUP BY p.id
Czy da się coś takiego osiągnąć w ActiveRecordzie tak, aby poszedł jeden select zamiast N + 1 (żeby nie zliczało dla każdego wiersza COUNT()).
Chciałbym po prostu coś takiego osiągnać “by the Rails way”, bo z tego co mi powtarzano to pisanie na pałe w SQL nie jest raczej wskazane.
1.9.2p318 :005 > Profile.select('id, first_name, last_name').join(:albums => :pieces).group('id, first_name, last_name').count
Profile Load (0.5ms) SELECT id, first_name, last_name FROM `profiles`
TypeError: can't convert Hash into String
from /home/hitsu/.rvm/gems/ruby-1.9.2-p318@artmrkt/gems/activerecord-3.1.3/lib/active_record/relation.rb:453:in `join'
from /home/hitsu/.rvm/gems/ruby-1.9.2-p318@artmrkt/gems/activerecord-3.1.3/lib/active_record/relation.rb:453:in `method_missing'
from (irb):5
from /home/hitsu/.rvm/gems/ruby-1.9.2-p318@artmrkt/gems/railties-3.1.3/lib/rails/commands/console.rb:45:in `start'
from /home/hitsu/.rvm/gems/ruby-1.9.2-p318@artmrkt/gems/railties-3.1.3/lib/rails/commands/console.rb:8:in `start'
from /home/hitsu/.rvm/gems/ruby-1.9.2-p318@artmrkt/gems/railties-3.1.3/lib/rails/commands.rb:40:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Edit:
Ostatecznie poszło:
Generalnie w normalnych bazach danych iz godznie ze standardem SQL (czytaj postgresql, oracle, SQL Server, DB2, generalnie wszystko oprócz MySQL) W zapytaniu grupowanym w sekcji select mogą występować jedynie pola po których grupujemy albo otoczone funkcjami agregującymi. MySQL pozwala na dopisywanie dowolnych pól co prowadzi najczęściej do nieokreślonego zachowania i cholernie ciężkich do znalezienia błędów.
Co do tego że rails wyciąga tylko last name wygląda jak feature railsowe, nie testowałem tego zapytania, pisałem z pamięci. Możliwe więc że da sie coś w tej sprawie zrobić. Powodzenia!