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.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

You May Also Like
Czytaj

Modyfikator Protected w Ruby

Rozmowy rekrutacyjne, a zwłaszcza ich część techniczna najczęściej przebiegają według jakiegoś określonego schematu. Łatwo przewidzieć pytania, jakie mogą…
Czytaj

Ruby Mixins – Include

Ruby jak każdy język obiektowy opiera się na dziedziczeniu. Ze względu na ograniczenie, w postaci dziedziczenia na raz…
Czytaj

Ruby Mixins – Extend

Ruby jak każdy język obiektowy opiera się na dziedziczeniu. Ze względu na ograniczenie, w postaci dziedziczenia na raz…
Czytaj

Spread Operator w Ruby i Ruby Ranges

Wszyscy pamiętamy jak rewolucyjne w świecie JavaScriptu okazało sie wprowadzenie tzw. <strong>spread operator</strong> wraz ze standardem ES6. Praca z kolekcjami…
Czytaj

Simple Command

Kto kiedykolwiek pracował w projekcie railsowym napewno widział tzw. fat controllers, gdzie logika poszczególnych akcji wpakowana jest bezpośrednio w…