SELECT (outlay - revenue) AS ile FROM AAA ORDER BY ile;
Coś takiego powinno być ok[/quote]
To by dzialalo, jednak mam metode zdefiniowana w modelu, ktora ta zaleznosc wylicza, i moje pytanie wlasnie bylo czy moge na tej metodzie bazowac, pomijajac :select w konstrukcji SQL’a do AR
Po pierwsze, czy wogole sie to da
Po drugie, czy Rails to jakos sensownie obsluzy ? Czy bedzie przy kazdej iteracj wykonywal metode wyliczeniowa “w kolko” ?
Niestety nie ma na to sprytnego sposobu. AR nie jest w stanie zbudować z tego sam SQLa. Jeśli pozostaniesz przy rozwiązaniu typu:
Human.all.sort_by(&:metoda_wyliczajaca)
to tak szybko jak przybędzie Ci rekordów w szukanej tabelce tak szybko stanie się to powolne. No chyba, że wcześniej będziesz używał jakiś filtrów i limitów, a dopiero na otrzymanej, względnie małej kolekcji zastosujesz sortowanie - wtedy powinno być ok.
Również składniałbym się do przerzucenia tego na bazę.
Jeśli chcesz sortować po takim polu to najoptymalniej byłoby utworzyć w tabeli bazy kolumnę debt i dodatkowo założyć na niej indeks.
Wtedy masz szybko działający i czysty kod.
Jedyny koszt to zwiększony czas zapisu do bazy, podczas którego będzie musiał być uaktualniony indeks oraz konieczność aktualizacji pola debt przy zmianie outlay lub revenue.
Rozwiązanie Human.all.sort_by(&:metoda_wyliczajaca) (czy jakiekolwiek podobne sortowanie w Ruby) jest najgorsze pod względem wydajnościowym - trzeba wyciągnąć wszystkie rekordy z bazy i je ręcznie posortować.
To jest dosyć istotny koszt. Oczywiście mniejszy niż narzut wydajnościowy przy sortowaniu po stronie Rubiego, ale mimo wszystko trzeba pamiętać, że trzeba o tym zawsze pamiętać kiedy modyfikuje się outlay lub revenue. Na szczęście w AR można do tego wykorzystać mechanizm śledzenia zmian w atrybutach (metoda “changes”), który powinien pozwolić załatwić sprawę “globalnie”. Niemniej jednak, jeśli baza może być modyfikowana przez innych klientów (tzn. za pomocą innych interfejsów niż Raislowy), to może okazać się, że dane w bazie są niespójne i wtedy jednak warto dodać odpowiedni mechanizm na poziomie BD.