2016-09-30 26 views
5

Jestem całkiem nowy dla ROR i Postgre i mam problemy z osiągnięciem tego.Group_by - Ruby/Rails + Postgres

Mam model Working_hour i model handlowca, gdzie kupiec ma wiele working_hours i working_hour przynależnych do Merchant. Kupiec może mieć dwie godziny pracy na ten dzień.

Moim zdaniem:

<% @merchant.working_hours.order(:day).group_by(&:day).each do |dia, whs| %> 
    <%= t(:"date.abbr_day_names")[dia.to_i] %> : 
    <% whs.each do |wh| %> 
     <li> 
     <%= wh.oppening_hour.to_formatted_s(:time) %> - 
     <%= wh.close_hour.to_formatted_s(:time) %> 
     </li> 
    <% end %> 
    <% end %> 

Kiedy wyświetlane w widoku zamówionej przez dzień dane pobierane są (zauważ, że godziny otwarcia są nieuporządkowane):

Mon: 
17:00-20:00 
10:00-13:00 
Tue: 
18:00-21:00 
10:00-13:00 

Chcę grupy przez dzień tygodnia i zamawianie najpierw przez dzień tygodnia i drugie przez godzina otwarcia:

Mon: 
10:00-13:00 
17:00-20:00 
Tue: 
10:00-13:00 
18:00-21:00 

Ale jak widać, obecnie używam warstwy ruby, aby to zrobić, co powoduje problemy z wydajnością. Jak osiągnąć to za pomocą warstwy bazy danych?

+0

Spróbuj wyszukać - postgres grupa przez tydzień - miałem ten sam problem z mysql i po przeczytaniu kilka artykułów potem dowiedziałem się więcej z sql i zrobiłem to, a następnie w szynach jej po prostu zwyczaj wybierz metodę na poziomie klasy ... –

+0

Czy masz jakiś 'default_scope', który miesza się z zamówieniem? – Pavan

+0

Nie @Pavan. Brak default_scope. – user1301037

Odpowiedz

2

Szybkie Postgres przykład, jeśli jesteś gotów do przechowywania danych w tabeli DB (na losowo utworzonym zbiorze):

-- The query: 
SELECT  to_char(mytime, 'day') as weekday,    -- example to get weekday name 
      extract(dow from mytime) as weekday_num,   -- example to get weekday number 
      format(           -- format the way example output was given 
       '%s - %s', 
       date_trunc('hour', opening_time)::time(0), -- get opening hour (without milliseconds) 
       date_trunc('hour', closing_time)::time(0)  -- get closing hour (without milliseconds) 
      ) as working_hours 
FROM  mytable 
GROUP BY mytime,   -- to secure accurate ordering by timestamp 
      weekday,   
      working_hours 
ORDER BY mytime, 
      working_hours; 

-- Result: 
    weekday | weekday_num | working_hours 
-----------+-------------+--------------------- 
monday |   1 | 08:00:00 - 17:00:00 
tuesday |   2 | 08:00:00 - 16:00:00 
tuesday |   2 | 08:00:00 - 17:00:00 
wednesday |   3 | 08:00:00 - 12:00:00 
thursday |   4 | 08:00:00 - 12:00:00 
thursday |   4 | 08:00:00 - 16:00:00 
friday |   5 | 08:00:00 - 15:00:00 
friday |   5 | 08:00:00 - 18:00:00 

PostgreSQL linki dokumentacji, które mogą się przydać:

https://www.postgresql.org/docs/current/static/functions-datetime.html https://www.postgresql.org/docs/current/static/functions-formatting.html https://www.postgresql.org/docs/current/static/functions-string.html#FUNCTIONS-STRING-FORMAT

PS Mam nadzieję, że daje kilka pomysłów, jak rozwiązać to w bazie danych.

+0

Jak mogę to połączyć na szynach? Używając zakresu? Czy możesz podać przykład, jak streścić to zapytanie na szynach? – user1301037

+0

@ user1301037 - Nie jestem ekspertem od Rubiego, ale nie używam Activerecord do wykonywania pomocy SQL w tym przykładzie jak podano tutaj: http://stackoverflow.com/questions/14824453/rails-raw-sql- przykład? –

2

Godzinę roboczą należy zamówić przez opening_hour, aby pokazać godzinę otwarcia w interfejsie użytkownika w porządku rosnącym. Po zamówieniu godziny pracy wynik można pogrupować według dnia.

<% @merchant.working_hours.order(:opening_hour).group_by(&:day).each do |dia, whs| %> <%= t(:"date.abbr_day_names")[dia.to_i] %> : <% whs.each do |wh| %> <li> <%= wh.opening_hour.to_formatted_s(:time) %> - <%= wh.close_hour.to_formatted_s(:time) %> </li> <% end %> <% end %>

+0

Powinieneś wyjaśnić, w jaki sposób ta odpowiedź odpowiada na pytanie. – Smar

2
<% day = nil %> 
<% @merchant.working_hours.order(:day, :oppening_hour).each do |wh| %> 
    <% if wh.day != day %> 
    <% day = wh.day %> 
    <%= t(:"date.abbr_day_names")[day.to_i] %> : 
    <% end %> 
    <li> 
    <%= wh.oppening_hour.to_formatted_s(:time) %> - 
    <%= wh.close_hour.to_formatted_s(:time) %> 
    </li> 
<% end %> 
0

Dlaczego po prostu nie można zamówić przez dwóch polach: przez "dzień" i "opening_hour"?

<% @merchant.working_hours.order(:day).order(:oppening_hour).group_by(&:day).each do |dia, whs| %> 
    <%= t(:"date.abbr_day_names")[dia.to_i] %> : 
    <% whs.each do |wh| %> 
     <li> 
     <%= wh.oppening_hour.to_formatted_s(:time) %> - 
     <%= wh.close_hour.to_formatted_s(:time) %> 
     </li> 
    <% end %> 
    <% end %>