Range i Date w Ruby on Rails
💡

Range i Date w Ruby on Rails

W jednym z poprzednich postów pokazywałem przykład zastosowania obiektu Range w Ruby. Ruby on Rails posiada własne rozszerzenie klasy Date, dzięki czemu bardzo wygodnie pracuje się z datami. Zero parsowania, zero konwersji, piszemy nasze helpery do obsługi dat, jak język naturalny, przez co kod możemy czytać płynnym angielski i momentami zapomnieć, że mamy do czynienia z językiem programowania. Dzisiaj pokażę Ci jak wykorzystać kombinację klas Range i Date w Ruby on Rails, żeby stworzyć czytelne sprawdzanie dat.

Specyfika Ruby pozwala na jeszcze jedną super rzecz – rozszerzanie corowych klas. W tym przykładzie rozszerzymy klasę Date dostarczaną przez Ruby on Rails.

Case:

W różnego rodzaju modułach raportowych lub dashboardach można spotkać się z operacjami polegającymi na porównywaniu dat, filtrowaniu dat z poprzedniego roku, miesiąca, tygodnia. Praca z datami w RoR i tak jest super przyjemna, ale poniższy snippet sprawi, że staje się jeszcze przyjemniejsza.

class Date

  def is_in? range
    range.include? self
  end

  class << self
    def today
      Date.current
    end

    def previous_year
      today.prev_year.beginning_of_year..today.prev_year.end_of_year
    end

    def current_year
      today.beginning_of_year..today.end_of_year
    end

    def previous_month
      today.prev_month.beginning_of_month..today.prev_month.end_of_month
    end

    def current_month
      today.beginning_of_month..today.end_of_month
    end

    def previous_week
      today.prev_week.beginning_of_week..today.prev_week.end_of_week
    end

    def current_week
      today.beginning_of_week..today.end_of_week
    end
  end

end

Rozszerzamy tutaj klasę Date.

W pierwszej kolejności deklaruję metodę instancji, która będzie sprawdzać czy data zawiera się w podanym zakresie. Jest to metoda instancji, czyli będzie wywoływania na instancji lub mówiąc prościej – bezpośrednio na dacie.

def is_in? range
  range.include? self
end

Następnie rozszerzam klasę Date o metody statyczne.

Nadpisuję metodę today.

def today
  Date.current
end

Tworzę metodę previous_year z wykorzystaniem Range, która zwraca zakres dat dla poprzedniego roku.

def previous_year
  today.prev_year.beginning_of_year..today.prev_year.end_of_year
end

Następnie tworzę metodę current_year, która zwraca zakres dat dla bieżącego roku.

  def current_year
    today.beginning_of_year..today.end_of_year
  end

W dalszej kolejności metody previous_monthcurrent_monthprevious_week i current_week.

def previous_month
  today.prev_month.beginning_of_month..today.prev_month.end_of_month
end
def current_month
  today.beginning_of_month..today.end_of_month
end
def previous_week
  today.prev_week.beginning_of_week..today.prev_week.end_of_week
end
def current_week
  today.beginning_of_week..today.end_of_week
end

Po stworzeniu tych pomocniczych metod możemy z łatwością pisać warunki sprawdzające daty.

Date.today.is_in?(Date.current_week)

invoice.date.is_in?(Date.previous_year)

Date.current_week.include?(report.date)

Połączenie klas Range i Date w Ruby on Rails to dobry pomysł na poprawę czytelności kodu.

W dokumentacji przeczytasz o klasie Range i o klasie Date.