has_many + include + sortowanie w includzie

Witajcie

Czy jest jakas opcja, zeby…

City: has_many :fuel_prices, :conditions=> {:fuel_state=> 1}, :include=> :fuel_type
FuelPrice: belongs_to :fuel_type

aby :include=> :fuel_type posortowac wg podanej kolumny?
Chodzi o to, zeby include=> fuel_type pobieral rekordy wg podanych id (co dziala ok), ale, zeby rowniez posortowal te kordy wg podanego pola.

rozwiazalem to tak
has_many :fuel_prices, :conditions=> {:fuel_state=> 1}, :include=> :fuel_type, :order=> ‘fuel_types.name’
ale powstaje pytanie z joinem, a chcialbym uniknac joina na rzec where id in…() order by…

no jak wiedz dokładnie co chcesz i nie masz pomyslu na AR to czemu tego w sql nie napisac?

pytam sie na forum, bo moze jest jakies rozwiazanie, ktorego nie moge znalezc, a w sql wszystko mozna napisac, ale jesli jest mozliwosc, aby napisac cos w AR, to czemu z tego nie korzystac :slight_smile:

poza tym jeszcze jedno pytanie, jak wg Ciebie powinien wygladac sql, zeby :include pobral wybrane rekordy wykorzystujac where id in + order by, zakladam, ze miales na mysli AR + sql, tak? (jesli tak, to jak “przemycic” sql do belongs_to - nie da sie chyba)

miałem na myśli stare dobre czyste sql i find_by_sql, jak nie masz pomysłu czemu nie. Wiem, że ne każdy tu na forum lubi i pochwala, ale jak się zna to czemu nie skorzystać.

Cześć :slight_smile:

Możesz zrobić coś takiego:

class FuelPrice < ActiveRecord::Base
belongs_to :city
has_one :fuel_type

named_scope :for_city, :conditions=> {:fuel_state=> 1}
named_scope :ordered, :include => :fuel_type, :order => ‘fuel_types.name’
end

class City < ActiveRecord::Base
has_many :fuel_prices

alias :fuel_prices_unordered :fuel_prices

def fuel_prices
fuel_prices_unordered.for_city.ordered
end
end

Pozwoli Ci to na:
- większy porządek w modelach (:order => ‘fuel_types.name’ zawarty w FuelPrice, który ma bezpośrednią relację z FuelType)
- jeśli używasz jakiegoś gema od resources (np resource_controller) otrzymasz działające collection z posortowanymi elementami
- w modelu FuelPrice masz named_scope dla poszczególnych części składowych zapytań
- dostęp do nieposortowanych elementów (poprzez alias fuel_prices_unordered)

Dlaczego chcesz uniknąć “JOIN” na rzecz “WHERE id IN ()” ?

Odnośnie przemycania “WHERE id IN ()” do “belongs_to” lub “has_many”: próbowałeś “:conditions” ? np:
:conditions => [“id IN (?)”, array_with_ids]
lub:
:conditions => “id IN (SELECT id FROM xxxx WHERE yyyy)”

Pozdrawiam :smiley:

Bardzo dziekuje za Twoja odpowiedz @Pr0d1r2, ale niestety mam relacje FuelPrice belongs_to FuelType, czyli w FP bedzie wiele cen dla FT, zmiana foreign_key nie pomaga, bo przy has_one musialoby byc odwolanie do tabeli fuel_prices ;/, ale Twoje rozwiazanie pokazalo mi, jak moge rozwiazac inne kwestie - dzieki!

Chce uniknac joina, poniewaz obie tabele beda sie rozrastaly, imho szybciej wykonaja sie 2 selecty, niz 1 join (oczywiscie mowa w tym konkretnym przypadku).

Benchmark or it didn’t happen.

Zaimplementuj prosto. Dodaj benchmark. Uruchom na produkcji. Poczekaj z dwa-trzy miesiące obserwując wzrost czasu wykonania. Gdy przekroczy 300ms i zacznie obciążać stronę to zacznij przemodelowywać.

Z doświadczenia wiemy, że nie należy za wcześnie optymalizować bazy. Najczęściej wystarczy dodać odpowiednie indeksy, żeby silnik poradził sobie wystarczająco szybko dla wydajnego działania.

Chcesz to mieć takie problemy (z popularnością), żeby je rozwiązywać w taki sposób.

Oraz: premature optimization is the root of all evil.