W jaki sposób zrobiłbyś to zapytanie podrzędne Rails używając Squeela?
Chcę zrestrukturyzować poniższe zapytanie za pomocą Squeel. Chciałbym to zrobić, aby móc połączyć łańcuchy operatorów i ponownie użyć logiki w różnych częściach zapytania.
User.find_by_sql("SELECT
users.*,
users.computed_metric,
users.age_in_seconds,
( users.computed_metric / age_in_seconds) as compound_computed_metric
from
(
select
users.*,
(users.id *2 ) as computed_metric,
(extract(epoch from now()) - extract(epoch from users.created_at) ) as age_in_seconds
from users
) as users")
Zapytanie musi działać w DB i nie powinno być hybrydowym rozwiązaniem Ruby, ponieważ musi zamawiać i kroić miliony rekordów.
Ustawiłem problem tak, aby działał normalnieuser
stół i abyś mógł grać z alternatywami do niego.
User
obiekt ze wszystkimi normalnymi atrybutamikażdy obiekt użytkownika powinien również zawieraćextra_metric_we_care_about
, age_in_seconds
icompound_computed_metric
zapytanie nie powinno powielać żadnej logiki, po prostu wypisując ciąg w wielu miejscach - chcę uniknąć dwukrotnego wykonywania tego samego[zaktualizowane] Zapytanie powinno być możliwe w DB, aby zestaw wyników, który może składać się z milionów rekordów, mógł zostać zamówiony i pocięty w DB przed powrotem do Rails[zaktualizowane] Rozwiązanie powinno działać dla DB PostgresPrzykład typu rozwiązania, które chciałbymPoniższe rozwiązanie nie działa, ale pokazuje typ elegancji, który mam nadzieję osiągnąć
class User < ActiveRecord::Base
# this doesn't work - it just illustrates what I want to achieve
def self.w_all_additional_metrics
select{ ['*',
computed_metric,
age_in_seconds,
(computed_metric / age_in_seconds).as(compound_computed_metric)]
}.from{ User.w.compound_computed_metric.w_age_in_seconds }
end
def self.w_computed_metric
where{ '(id *2 ) as computed_metric' }
end
def self.w_age_in_seconds
where{ '(extract(epoch from now()) - extract(epoch from created_at) ) as age_in_seconds' }
end
end
Powinieneś być w stanie uruchomić to w oparciu o istniejącą bazę danychPamiętaj, że nieco opracowałem problem, abyś mógł korzystać z istniejącegoUser
klasa i baw się nią w konsoli.