2017-05-11 42 views
5

Czy Rails naprawdę nie obsługuje poprawnie typ danych interwału PostgreSQL?Typ danych Rails 5 i PostgreSQL "Interval"

Musiałem użyć this Stack Overflow answer z 2013 roku, aby utworzyć kolumnę z interwałem, a teraz wygląda na to, że będę musiał użyć this piece of code z 2013 roku, aby ActiveRecord traktował interwał jako coś innego niż ciąg.

Czy tak to jest? Czy lepiej jest po prostu użyć typu danych liczbowych całkowitych do reprezentowania liczby minut zamiast?

+1

Źródła szyn wydają się wymieniać "interwał" w [odpowiednim] (https://github.com/rails/rails/blob/v5.1.1/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L112) [miejsca] (https://github.com/rails/rails/blob/v5.1.1/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb#L91), więc wygląda na Rails5. Odpowiadałbym, ale nie mam konfiguracji Rails5, by zweryfikować moje domysły i nie jestem pewien jak obszerna jest obsługa (jeśli tak naprawdę tam jest). –

+0

Dzięki za to. Wygląda na to, że niektóre z "interwałów" zostały dodane całkiem niedawno, więc mam zamiar przejść do wersji 5.1.1 i sprawdzić, czy działa lepiej. –

+1

Wygląda na to, że uaktualnienie naprawia pierwszy problem (pozwalający w łatwy sposób utworzyć kolumnę interwału), ale nie rozwiązuje drugiego (o activerecord interpretuje kolumnę jako interwał, a nie ciąg). Myślę, że łatwiej jest po prostu użyć typu danych liczbowych całkowitych. Dzięki za pomoc. –

Odpowiedz

1

Miałem podobny problem i poszedłem z określeniem metody odczytu dla konkretnej kolumny w modelu ActiveRecord. W ten sposób:

class DivingResults < ActiveRecord::Base 
    # This overrides the same method for db column, generated by rails 
    def underwater_duration 
    interval_from_db = super 
    time_parts = interval_from_db.split(':') 
    if time_parts.size > 1 # Handle formats like 17:04:41.478432 
     units = %i(hours minutes seconds) 
     in_seconds = time_parts 
     .map.with_index { |t,i| t.to_i.public_send(units[i]) } 
     .reduce(&:+) # Turn each part to seconds and then sum 
     ActiveSupport::Duration.build in_seconds 
    else # Handle formats in seconds 
     ActiveSupport::Duration.build(interval_from_db.to_i) 
    end 
    end 
end 

Pozwala to na użycie instancji ActiveSupport::Duration w innym miejscu. Mamy nadzieję, że Railsy zaczną automatycznie obsługiwać typ danych interwału PostgreSQL w najbliższej przyszłości.