2016-12-03 2 views
1

В моем проекте rails (with postgresql) у меня есть Event-модель с start_date и end_date полями. Диапазоны дат события не могут перекрываться. Я хочу получить все даты с событием.Активная запись: получить все даты в нескольких диапазонах

Например:

| event id | start_date | end_date | 
| :------: | :--------: | :--------: | 
| 51  | 2011-09-27 | 2011-09-29 | 
| 70  | 2014-07-23 | 2014-07-26 | 
| 71  | 2014-06-30 | 2014-07-01 | 
| 77  | 2016-03-10 | 2016-03-11 | 

Выход:

[ 
    2011-09-27, 
    2011-09-28, 
    2011-09-29, 
    2014-07-23, 
    2014-07-24, 
    2014-07-25, 
    2015-08-26, 
    2014-06-30, 
    2014-06-31, 
    2014-07-01, 
    2016-03-10, 
    2013-03-11 
] 

Я стараюсь делать много и получить результат с этим кодом:

Event 
    .pluck(:start_date, :end_date) 
    .map(&:compact).reject(&:empty?) # I have events with null start_date and end_date 
    .map{ |start_date, end_date| 
    (start_date.to_date..end_date.to_date).map(&:to_s) 
    } 
    .flatten 

Но я думаю, что это некрасиво , есть ли элегантный способ решить мою проблему? Может быть, с postgresql, но я новичок в postgresql.

+0

Ваш код будет выглядеть лучше, если вы просто реорганизован вокруг метода объема и экземпляра, так что вы можете: Event.has_start_and_end.dates_in_range.flatten –

ответ

0

На модели event.rb

def get_dates 
    [created_at, updated_at] 
end 

И получить все даты по:

Event.all.map(&:get_dates).flatten 

Update

изменить функцию get_dates.

def get_dates 
    (Date.parse(start_date.to_s)..Date.parse(end_date.to_s)).to_a 
end 
+0

Спасибо за ответ, но это не то, что я хочу получить. В этом случае я получаю только даты начала и окончания **, но не даты между 'start_date' и' end_date' **. –

+0

Ах, извините. просто измените функцию get_dates, посмотрите мое обновление –

0

Я нашел другой способ решить мою проблему с SQL запросом

SQL Fiddle

PostgreSQL 9.3 Схема установки:

CREATE TABLE events (
    id integer NOT NULL, 
    start_date date, 
    end_date date 
)/ 

INSERT INTO events (id, start_date, end_date) VALUES (51, '2011-09-27', '2011-09-29')/ 
INSERT INTO events (id, start_date, end_date) VALUES (70, '2014-07-23', '2014-07-26')/ 
INSERT INTO events (id, start_date, end_date) VALUES (71, '2014-06-30', '2014-07-01')/ 
INSERT INTO events (id, start_date, end_date) VALUES (77, '2016-03-10', '2016-03-11')/ 

Запрос 1:

WITH duration AS (
    SELECT start_date as begins 
    , end_date as ends 
    FROM events 
    ) 
SELECT generate_series(duration.begins, duration.ends, '1 day':: interval):: date 
FROM duration; 

Results:

|    generate_series | 
|-----------------------------| 
| September, 27 2011 00:00:00 | 
| September, 28 2011 00:00:00 | 
| September, 29 2011 00:00:00 | 
|  July, 23 2014 00:00:00 | 
|  July, 24 2014 00:00:00 | 
|  July, 25 2014 00:00:00 | 
|  July, 26 2014 00:00:00 | 
|  June, 30 2014 00:00:00 | 
|  July, 01 2014 00:00:00 | 
|  March, 10 2016 00:00:00 | 
|  March, 11 2016 00:00:00 | 
Смежные вопросы